18c2ecf20Sopenharmony_ci#!/bin/sh 28c2ecf20Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0 38c2ecf20Sopenharmony_ci# 48c2ecf20Sopenharmony_ci# Kselftest framework defines: ksft_pass=0, ksft_fail=1, ksft_skip=4 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ciVERBOSE="${VERBOSE:-1}" 78c2ecf20Sopenharmony_ciIKCONFIG="/tmp/config-`uname -r`" 88c2ecf20Sopenharmony_ciKERNEL_IMAGE="/boot/vmlinuz-`uname -r`" 98c2ecf20Sopenharmony_ciSECURITYFS=$(grep "securityfs" /proc/mounts | awk '{print $2}') 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_cilog_info() 128c2ecf20Sopenharmony_ci{ 138c2ecf20Sopenharmony_ci [ $VERBOSE -ne 0 ] && echo "[INFO] $1" 148c2ecf20Sopenharmony_ci} 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci# The ksefltest framework requirement returns 0 for PASS. 178c2ecf20Sopenharmony_cilog_pass() 188c2ecf20Sopenharmony_ci{ 198c2ecf20Sopenharmony_ci [ $VERBOSE -ne 0 ] && echo "$1 [PASS]" 208c2ecf20Sopenharmony_ci exit 0 218c2ecf20Sopenharmony_ci} 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci# The ksefltest framework requirement returns 1 for FAIL. 248c2ecf20Sopenharmony_cilog_fail() 258c2ecf20Sopenharmony_ci{ 268c2ecf20Sopenharmony_ci [ $VERBOSE -ne 0 ] && echo "$1 [FAIL]" 278c2ecf20Sopenharmony_ci exit 1 288c2ecf20Sopenharmony_ci} 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci# The ksefltest framework requirement returns 4 for SKIP. 318c2ecf20Sopenharmony_cilog_skip() 328c2ecf20Sopenharmony_ci{ 338c2ecf20Sopenharmony_ci [ $VERBOSE -ne 0 ] && echo "$1" 348c2ecf20Sopenharmony_ci exit 4 358c2ecf20Sopenharmony_ci} 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci# Check efivar SecureBoot-$(the UUID) and SetupMode-$(the UUID). 388c2ecf20Sopenharmony_ci# (Based on kdump-lib.sh) 398c2ecf20Sopenharmony_ciget_efivarfs_secureboot_mode() 408c2ecf20Sopenharmony_ci{ 418c2ecf20Sopenharmony_ci local efivarfs="/sys/firmware/efi/efivars" 428c2ecf20Sopenharmony_ci local secure_boot_file="" 438c2ecf20Sopenharmony_ci local setup_mode_file="" 448c2ecf20Sopenharmony_ci local secureboot_mode=0 458c2ecf20Sopenharmony_ci local setup_mode=0 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci # Make sure that efivar_fs is mounted in the normal location 488c2ecf20Sopenharmony_ci if ! grep -q "^\S\+ $efivarfs efivarfs" /proc/mounts; then 498c2ecf20Sopenharmony_ci log_info "efivars is not mounted on $efivarfs" 508c2ecf20Sopenharmony_ci return 0; 518c2ecf20Sopenharmony_ci fi 528c2ecf20Sopenharmony_ci secure_boot_file=$(find "$efivarfs" -name SecureBoot-* 2>/dev/null) 538c2ecf20Sopenharmony_ci setup_mode_file=$(find "$efivarfs" -name SetupMode-* 2>/dev/null) 548c2ecf20Sopenharmony_ci if [ -f "$secure_boot_file" ] && [ -f "$setup_mode_file" ]; then 558c2ecf20Sopenharmony_ci secureboot_mode=$(hexdump -v -e '/1 "%d\ "' \ 568c2ecf20Sopenharmony_ci "$secure_boot_file"|cut -d' ' -f 5) 578c2ecf20Sopenharmony_ci setup_mode=$(hexdump -v -e '/1 "%d\ "' \ 588c2ecf20Sopenharmony_ci "$setup_mode_file"|cut -d' ' -f 5) 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci if [ $secureboot_mode -eq 1 ] && [ $setup_mode -eq 0 ]; then 618c2ecf20Sopenharmony_ci log_info "secure boot mode enabled (CONFIG_EFIVAR_FS)" 628c2ecf20Sopenharmony_ci return 1; 638c2ecf20Sopenharmony_ci fi 648c2ecf20Sopenharmony_ci fi 658c2ecf20Sopenharmony_ci return 0; 668c2ecf20Sopenharmony_ci} 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ciget_efi_var_secureboot_mode() 698c2ecf20Sopenharmony_ci{ 708c2ecf20Sopenharmony_ci local efi_vars 718c2ecf20Sopenharmony_ci local secure_boot_file 728c2ecf20Sopenharmony_ci local setup_mode_file 738c2ecf20Sopenharmony_ci local secureboot_mode 748c2ecf20Sopenharmony_ci local setup_mode 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci if [ ! -d "$efi_vars" ]; then 778c2ecf20Sopenharmony_ci log_skip "efi_vars is not enabled\n" 788c2ecf20Sopenharmony_ci fi 798c2ecf20Sopenharmony_ci secure_boot_file=$(find "$efi_vars" -name SecureBoot-* 2>/dev/null) 808c2ecf20Sopenharmony_ci setup_mode_file=$(find "$efi_vars" -name SetupMode-* 2>/dev/null) 818c2ecf20Sopenharmony_ci if [ -f "$secure_boot_file/data" ] && \ 828c2ecf20Sopenharmony_ci [ -f "$setup_mode_file/data" ]; then 838c2ecf20Sopenharmony_ci secureboot_mode=`od -An -t u1 "$secure_boot_file/data"` 848c2ecf20Sopenharmony_ci setup_mode=`od -An -t u1 "$setup_mode_file/data"` 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci if [ $secureboot_mode -eq 1 ] && [ $setup_mode -eq 0 ]; then 878c2ecf20Sopenharmony_ci log_info "secure boot mode enabled (CONFIG_EFI_VARS)" 888c2ecf20Sopenharmony_ci return 1; 898c2ecf20Sopenharmony_ci fi 908c2ecf20Sopenharmony_ci fi 918c2ecf20Sopenharmony_ci return 0; 928c2ecf20Sopenharmony_ci} 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci# Check efivar SecureBoot-$(the UUID) and SetupMode-$(the UUID). 958c2ecf20Sopenharmony_ci# The secure boot mode can be accessed either as the last integer 968c2ecf20Sopenharmony_ci# of "od -An -t u1 /sys/firmware/efi/efivars/SecureBoot-*" or from 978c2ecf20Sopenharmony_ci# "od -An -t u1 /sys/firmware/efi/vars/SecureBoot-*/data". The efi 988c2ecf20Sopenharmony_ci# SetupMode can be similarly accessed. 998c2ecf20Sopenharmony_ci# Return 1 for SecureBoot mode enabled and SetupMode mode disabled. 1008c2ecf20Sopenharmony_ciget_secureboot_mode() 1018c2ecf20Sopenharmony_ci{ 1028c2ecf20Sopenharmony_ci local secureboot_mode=0 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci get_efivarfs_secureboot_mode 1058c2ecf20Sopenharmony_ci secureboot_mode=$? 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci # fallback to using the efi_var files 1088c2ecf20Sopenharmony_ci if [ $secureboot_mode -eq 0 ]; then 1098c2ecf20Sopenharmony_ci get_efi_var_secureboot_mode 1108c2ecf20Sopenharmony_ci secureboot_mode=$? 1118c2ecf20Sopenharmony_ci fi 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci if [ $secureboot_mode -eq 0 ]; then 1148c2ecf20Sopenharmony_ci log_info "secure boot mode not enabled" 1158c2ecf20Sopenharmony_ci fi 1168c2ecf20Sopenharmony_ci return $secureboot_mode; 1178c2ecf20Sopenharmony_ci} 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_cirequire_root_privileges() 1208c2ecf20Sopenharmony_ci{ 1218c2ecf20Sopenharmony_ci if [ $(id -ru) -ne 0 ]; then 1228c2ecf20Sopenharmony_ci log_skip "requires root privileges" 1238c2ecf20Sopenharmony_ci fi 1248c2ecf20Sopenharmony_ci} 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci# Look for config option in Kconfig file. 1278c2ecf20Sopenharmony_ci# Return 1 for found and 0 for not found. 1288c2ecf20Sopenharmony_cikconfig_enabled() 1298c2ecf20Sopenharmony_ci{ 1308c2ecf20Sopenharmony_ci local config="$1" 1318c2ecf20Sopenharmony_ci local msg="$2" 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci grep -E -q $config $IKCONFIG 1348c2ecf20Sopenharmony_ci if [ $? -eq 0 ]; then 1358c2ecf20Sopenharmony_ci log_info "$msg" 1368c2ecf20Sopenharmony_ci return 1 1378c2ecf20Sopenharmony_ci fi 1388c2ecf20Sopenharmony_ci return 0 1398c2ecf20Sopenharmony_ci} 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci# Attempt to get the kernel config first via proc, and then by 1428c2ecf20Sopenharmony_ci# extracting it from the kernel image or the configs.ko using 1438c2ecf20Sopenharmony_ci# scripts/extract-ikconfig. 1448c2ecf20Sopenharmony_ci# Return 1 for found. 1458c2ecf20Sopenharmony_ciget_kconfig() 1468c2ecf20Sopenharmony_ci{ 1478c2ecf20Sopenharmony_ci local proc_config="/proc/config.gz" 1488c2ecf20Sopenharmony_ci local module_dir="/lib/modules/`uname -r`" 1498c2ecf20Sopenharmony_ci local configs_module="$module_dir/kernel/kernel/configs.ko" 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci if [ ! -f $proc_config ]; then 1528c2ecf20Sopenharmony_ci modprobe configs > /dev/null 2>&1 1538c2ecf20Sopenharmony_ci fi 1548c2ecf20Sopenharmony_ci if [ -f $proc_config ]; then 1558c2ecf20Sopenharmony_ci cat $proc_config | gunzip > $IKCONFIG 2>/dev/null 1568c2ecf20Sopenharmony_ci if [ $? -eq 0 ]; then 1578c2ecf20Sopenharmony_ci return 1 1588c2ecf20Sopenharmony_ci fi 1598c2ecf20Sopenharmony_ci fi 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci local extract_ikconfig="$module_dir/source/scripts/extract-ikconfig" 1628c2ecf20Sopenharmony_ci if [ ! -f $extract_ikconfig ]; then 1638c2ecf20Sopenharmony_ci log_skip "extract-ikconfig not found" 1648c2ecf20Sopenharmony_ci fi 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci $extract_ikconfig $KERNEL_IMAGE > $IKCONFIG 2>/dev/null 1678c2ecf20Sopenharmony_ci if [ $? -eq 1 ]; then 1688c2ecf20Sopenharmony_ci if [ ! -f $configs_module ]; then 1698c2ecf20Sopenharmony_ci log_skip "CONFIG_IKCONFIG not enabled" 1708c2ecf20Sopenharmony_ci fi 1718c2ecf20Sopenharmony_ci $extract_ikconfig $configs_module > $IKCONFIG 1728c2ecf20Sopenharmony_ci if [ $? -eq 1 ]; then 1738c2ecf20Sopenharmony_ci log_skip "CONFIG_IKCONFIG not enabled" 1748c2ecf20Sopenharmony_ci fi 1758c2ecf20Sopenharmony_ci fi 1768c2ecf20Sopenharmony_ci return 1 1778c2ecf20Sopenharmony_ci} 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci# Make sure that securityfs is mounted 1808c2ecf20Sopenharmony_cimount_securityfs() 1818c2ecf20Sopenharmony_ci{ 1828c2ecf20Sopenharmony_ci if [ -z $SECURITYFS ]; then 1838c2ecf20Sopenharmony_ci SECURITYFS=/sys/kernel/security 1848c2ecf20Sopenharmony_ci mount -t securityfs security $SECURITYFS 1858c2ecf20Sopenharmony_ci fi 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci if [ ! -d "$SECURITYFS" ]; then 1888c2ecf20Sopenharmony_ci log_fail "$SECURITYFS :securityfs is not mounted" 1898c2ecf20Sopenharmony_ci fi 1908c2ecf20Sopenharmony_ci} 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci# The policy rule format is an "action" followed by key-value pairs. This 1938c2ecf20Sopenharmony_ci# function supports up to two key-value pairs, in any order. 1948c2ecf20Sopenharmony_ci# For example: action func=<keyword> [appraise_type=<type>] 1958c2ecf20Sopenharmony_ci# Return 1 for found and 0 for not found. 1968c2ecf20Sopenharmony_cicheck_ima_policy() 1978c2ecf20Sopenharmony_ci{ 1988c2ecf20Sopenharmony_ci local action="$1" 1998c2ecf20Sopenharmony_ci local keypair1="$2" 2008c2ecf20Sopenharmony_ci local keypair2="$3" 2018c2ecf20Sopenharmony_ci local ret=0 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci mount_securityfs 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci local ima_policy=$SECURITYFS/ima/policy 2068c2ecf20Sopenharmony_ci if [ ! -e $ima_policy ]; then 2078c2ecf20Sopenharmony_ci log_fail "$ima_policy not found" 2088c2ecf20Sopenharmony_ci fi 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci if [ -n $keypair2 ]; then 2118c2ecf20Sopenharmony_ci grep -e "^$action.*$keypair1" "$ima_policy" | \ 2128c2ecf20Sopenharmony_ci grep -q -e "$keypair2" 2138c2ecf20Sopenharmony_ci else 2148c2ecf20Sopenharmony_ci grep -q -e "^$action.*$keypair1" "$ima_policy" 2158c2ecf20Sopenharmony_ci fi 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci # invert "grep -q" result, returning 1 for found. 2188c2ecf20Sopenharmony_ci [ $? -eq 0 ] && ret=1 2198c2ecf20Sopenharmony_ci return $ret 2208c2ecf20Sopenharmony_ci} 221