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