xref: /OK3568_Linux_fs/kernel/tools/testing/selftests/kexec/kexec_common_lib.sh (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#!/bin/sh
2*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0
3*4882a593Smuzhiyun#
4*4882a593Smuzhiyun# Kselftest framework defines: ksft_pass=0, ksft_fail=1, ksft_skip=4
5*4882a593Smuzhiyun
6*4882a593SmuzhiyunVERBOSE="${VERBOSE:-1}"
7*4882a593SmuzhiyunIKCONFIG="/tmp/config-`uname -r`"
8*4882a593SmuzhiyunKERNEL_IMAGE="/boot/vmlinuz-`uname -r`"
9*4882a593SmuzhiyunSECURITYFS=$(grep "securityfs" /proc/mounts | awk '{print $2}')
10*4882a593Smuzhiyun
11*4882a593Smuzhiyunlog_info()
12*4882a593Smuzhiyun{
13*4882a593Smuzhiyun	[ $VERBOSE -ne 0 ] && echo "[INFO] $1"
14*4882a593Smuzhiyun}
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun# The ksefltest framework requirement returns 0 for PASS.
17*4882a593Smuzhiyunlog_pass()
18*4882a593Smuzhiyun{
19*4882a593Smuzhiyun	[ $VERBOSE -ne 0 ] && echo "$1 [PASS]"
20*4882a593Smuzhiyun	exit 0
21*4882a593Smuzhiyun}
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun# The ksefltest framework requirement returns 1 for FAIL.
24*4882a593Smuzhiyunlog_fail()
25*4882a593Smuzhiyun{
26*4882a593Smuzhiyun	[ $VERBOSE -ne 0 ] && echo "$1 [FAIL]"
27*4882a593Smuzhiyun	exit 1
28*4882a593Smuzhiyun}
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun# The ksefltest framework requirement returns 4 for SKIP.
31*4882a593Smuzhiyunlog_skip()
32*4882a593Smuzhiyun{
33*4882a593Smuzhiyun	[ $VERBOSE -ne 0 ] && echo "$1"
34*4882a593Smuzhiyun	exit 4
35*4882a593Smuzhiyun}
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun# Check efivar SecureBoot-$(the UUID) and SetupMode-$(the UUID).
38*4882a593Smuzhiyun# (Based on kdump-lib.sh)
39*4882a593Smuzhiyunget_efivarfs_secureboot_mode()
40*4882a593Smuzhiyun{
41*4882a593Smuzhiyun	local efivarfs="/sys/firmware/efi/efivars"
42*4882a593Smuzhiyun	local secure_boot_file=""
43*4882a593Smuzhiyun	local setup_mode_file=""
44*4882a593Smuzhiyun	local secureboot_mode=0
45*4882a593Smuzhiyun	local setup_mode=0
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun	# Make sure that efivar_fs is mounted in the normal location
48*4882a593Smuzhiyun	if ! grep -q "^\S\+ $efivarfs efivarfs" /proc/mounts; then
49*4882a593Smuzhiyun		log_info "efivars is not mounted on $efivarfs"
50*4882a593Smuzhiyun		return 0;
51*4882a593Smuzhiyun	fi
52*4882a593Smuzhiyun	secure_boot_file=$(find "$efivarfs" -name SecureBoot-* 2>/dev/null)
53*4882a593Smuzhiyun	setup_mode_file=$(find "$efivarfs" -name SetupMode-* 2>/dev/null)
54*4882a593Smuzhiyun	if [ -f "$secure_boot_file" ] && [ -f "$setup_mode_file" ]; then
55*4882a593Smuzhiyun		secureboot_mode=$(hexdump -v -e '/1 "%d\ "' \
56*4882a593Smuzhiyun			"$secure_boot_file"|cut -d' ' -f 5)
57*4882a593Smuzhiyun		setup_mode=$(hexdump -v -e '/1 "%d\ "' \
58*4882a593Smuzhiyun			"$setup_mode_file"|cut -d' ' -f 5)
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun		if [ $secureboot_mode -eq 1 ] && [ $setup_mode -eq 0 ]; then
61*4882a593Smuzhiyun			log_info "secure boot mode enabled (CONFIG_EFIVAR_FS)"
62*4882a593Smuzhiyun			return 1;
63*4882a593Smuzhiyun		fi
64*4882a593Smuzhiyun	fi
65*4882a593Smuzhiyun	return 0;
66*4882a593Smuzhiyun}
67*4882a593Smuzhiyun
68*4882a593Smuzhiyunget_efi_var_secureboot_mode()
69*4882a593Smuzhiyun{
70*4882a593Smuzhiyun	local efi_vars
71*4882a593Smuzhiyun	local secure_boot_file
72*4882a593Smuzhiyun	local setup_mode_file
73*4882a593Smuzhiyun	local secureboot_mode
74*4882a593Smuzhiyun	local setup_mode
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun	if [ ! -d "$efi_vars" ]; then
77*4882a593Smuzhiyun		log_skip "efi_vars is not enabled\n"
78*4882a593Smuzhiyun	fi
79*4882a593Smuzhiyun	secure_boot_file=$(find "$efi_vars" -name SecureBoot-* 2>/dev/null)
80*4882a593Smuzhiyun	setup_mode_file=$(find "$efi_vars" -name SetupMode-* 2>/dev/null)
81*4882a593Smuzhiyun	if [ -f "$secure_boot_file/data" ] && \
82*4882a593Smuzhiyun	   [ -f "$setup_mode_file/data" ]; then
83*4882a593Smuzhiyun		secureboot_mode=`od -An -t u1 "$secure_boot_file/data"`
84*4882a593Smuzhiyun		setup_mode=`od -An -t u1 "$setup_mode_file/data"`
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun		if [ $secureboot_mode -eq 1 ] && [ $setup_mode -eq 0 ]; then
87*4882a593Smuzhiyun			log_info "secure boot mode enabled (CONFIG_EFI_VARS)"
88*4882a593Smuzhiyun			return 1;
89*4882a593Smuzhiyun		fi
90*4882a593Smuzhiyun	fi
91*4882a593Smuzhiyun	return 0;
92*4882a593Smuzhiyun}
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun# Check efivar SecureBoot-$(the UUID) and SetupMode-$(the UUID).
95*4882a593Smuzhiyun# The secure boot mode can be accessed either as the last integer
96*4882a593Smuzhiyun# of "od -An -t u1 /sys/firmware/efi/efivars/SecureBoot-*" or from
97*4882a593Smuzhiyun# "od -An -t u1 /sys/firmware/efi/vars/SecureBoot-*/data".  The efi
98*4882a593Smuzhiyun# SetupMode can be similarly accessed.
99*4882a593Smuzhiyun# Return 1 for SecureBoot mode enabled and SetupMode mode disabled.
100*4882a593Smuzhiyunget_secureboot_mode()
101*4882a593Smuzhiyun{
102*4882a593Smuzhiyun	local secureboot_mode=0
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun	get_efivarfs_secureboot_mode
105*4882a593Smuzhiyun	secureboot_mode=$?
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun	# fallback to using the efi_var files
108*4882a593Smuzhiyun	if [ $secureboot_mode -eq 0 ]; then
109*4882a593Smuzhiyun		get_efi_var_secureboot_mode
110*4882a593Smuzhiyun		secureboot_mode=$?
111*4882a593Smuzhiyun	fi
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun	if [ $secureboot_mode -eq 0 ]; then
114*4882a593Smuzhiyun		log_info "secure boot mode not enabled"
115*4882a593Smuzhiyun	fi
116*4882a593Smuzhiyun	return $secureboot_mode;
117*4882a593Smuzhiyun}
118*4882a593Smuzhiyun
119*4882a593Smuzhiyunrequire_root_privileges()
120*4882a593Smuzhiyun{
121*4882a593Smuzhiyun	if [ $(id -ru) -ne 0 ]; then
122*4882a593Smuzhiyun		log_skip "requires root privileges"
123*4882a593Smuzhiyun	fi
124*4882a593Smuzhiyun}
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun# Look for config option in Kconfig file.
127*4882a593Smuzhiyun# Return 1 for found and 0 for not found.
128*4882a593Smuzhiyunkconfig_enabled()
129*4882a593Smuzhiyun{
130*4882a593Smuzhiyun	local config="$1"
131*4882a593Smuzhiyun	local msg="$2"
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun	grep -E -q $config $IKCONFIG
134*4882a593Smuzhiyun	if [ $? -eq 0 ]; then
135*4882a593Smuzhiyun		log_info "$msg"
136*4882a593Smuzhiyun		return 1
137*4882a593Smuzhiyun	fi
138*4882a593Smuzhiyun	return 0
139*4882a593Smuzhiyun}
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun# Attempt to get the kernel config first via proc, and then by
142*4882a593Smuzhiyun# extracting it from the kernel image or the configs.ko using
143*4882a593Smuzhiyun# scripts/extract-ikconfig.
144*4882a593Smuzhiyun# Return 1 for found.
145*4882a593Smuzhiyunget_kconfig()
146*4882a593Smuzhiyun{
147*4882a593Smuzhiyun	local proc_config="/proc/config.gz"
148*4882a593Smuzhiyun	local module_dir="/lib/modules/`uname -r`"
149*4882a593Smuzhiyun	local configs_module="$module_dir/kernel/kernel/configs.ko"
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun	if [ ! -f $proc_config ]; then
152*4882a593Smuzhiyun		modprobe configs > /dev/null 2>&1
153*4882a593Smuzhiyun	fi
154*4882a593Smuzhiyun	if [ -f $proc_config ]; then
155*4882a593Smuzhiyun		cat $proc_config | gunzip > $IKCONFIG 2>/dev/null
156*4882a593Smuzhiyun		if [ $? -eq 0 ]; then
157*4882a593Smuzhiyun			return 1
158*4882a593Smuzhiyun		fi
159*4882a593Smuzhiyun	fi
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun	local extract_ikconfig="$module_dir/source/scripts/extract-ikconfig"
162*4882a593Smuzhiyun	if [ ! -f $extract_ikconfig ]; then
163*4882a593Smuzhiyun		log_skip "extract-ikconfig not found"
164*4882a593Smuzhiyun	fi
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun	$extract_ikconfig $KERNEL_IMAGE > $IKCONFIG 2>/dev/null
167*4882a593Smuzhiyun	if [ $? -eq 1 ]; then
168*4882a593Smuzhiyun		if [ ! -f $configs_module ]; then
169*4882a593Smuzhiyun			log_skip "CONFIG_IKCONFIG not enabled"
170*4882a593Smuzhiyun		fi
171*4882a593Smuzhiyun		$extract_ikconfig $configs_module > $IKCONFIG
172*4882a593Smuzhiyun		if [ $? -eq 1 ]; then
173*4882a593Smuzhiyun			log_skip "CONFIG_IKCONFIG not enabled"
174*4882a593Smuzhiyun		fi
175*4882a593Smuzhiyun	fi
176*4882a593Smuzhiyun	return 1
177*4882a593Smuzhiyun}
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun# Make sure that securityfs is mounted
180*4882a593Smuzhiyunmount_securityfs()
181*4882a593Smuzhiyun{
182*4882a593Smuzhiyun	if [ -z $SECURITYFS ]; then
183*4882a593Smuzhiyun		SECURITYFS=/sys/kernel/security
184*4882a593Smuzhiyun		mount -t securityfs security $SECURITYFS
185*4882a593Smuzhiyun	fi
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun	if [ ! -d "$SECURITYFS" ]; then
188*4882a593Smuzhiyun		log_fail "$SECURITYFS :securityfs is not mounted"
189*4882a593Smuzhiyun	fi
190*4882a593Smuzhiyun}
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun# The policy rule format is an "action" followed by key-value pairs.  This
193*4882a593Smuzhiyun# function supports up to two key-value pairs, in any order.
194*4882a593Smuzhiyun# For example: action func=<keyword> [appraise_type=<type>]
195*4882a593Smuzhiyun# Return 1 for found and 0 for not found.
196*4882a593Smuzhiyuncheck_ima_policy()
197*4882a593Smuzhiyun{
198*4882a593Smuzhiyun	local action="$1"
199*4882a593Smuzhiyun	local keypair1="$2"
200*4882a593Smuzhiyun	local keypair2="$3"
201*4882a593Smuzhiyun	local ret=0
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun	mount_securityfs
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun	local ima_policy=$SECURITYFS/ima/policy
206*4882a593Smuzhiyun	if [ ! -e $ima_policy ]; then
207*4882a593Smuzhiyun		log_fail "$ima_policy not found"
208*4882a593Smuzhiyun	fi
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun	if [ -n $keypair2 ]; then
211*4882a593Smuzhiyun		grep -e "^$action.*$keypair1" "$ima_policy" | \
212*4882a593Smuzhiyun			grep -q -e "$keypair2"
213*4882a593Smuzhiyun	else
214*4882a593Smuzhiyun		grep -q -e "^$action.*$keypair1" "$ima_policy"
215*4882a593Smuzhiyun	fi
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun	# invert "grep -q" result, returning 1 for found.
218*4882a593Smuzhiyun	[ $? -eq 0 ] && ret=1
219*4882a593Smuzhiyun	return $ret
220*4882a593Smuzhiyun}
221