1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4set -e 5set -u 6set -o pipefail 7 8IMA_POLICY_FILE="/sys/kernel/security/ima/policy" 9TEST_BINARY="/bin/true" 10VERBOSE="${SELFTESTS_VERBOSE:=0}" 11LOG_FILE="$(mktemp /tmp/ima_setup.XXXX.log)" 12 13usage() 14{ 15 echo "Usage: $0 <setup|cleanup|run|modify-bin|restore-bin|load-policy> <existing_tmp_dir>" 16 exit 1 17} 18 19ensure_mount_securityfs() 20{ 21 local securityfs_dir=$(grep "securityfs" /proc/mounts | awk '{print $2}') 22 23 if [ -z "${securityfs_dir}" ]; then 24 securityfs_dir=/sys/kernel/security 25 mount -t securityfs security "${securityfs_dir}" 26 fi 27 28 if [ ! -d "${securityfs_dir}" ]; then 29 echo "${securityfs_dir}: securityfs is not mounted" && exit 1 30 fi 31} 32 33setup() 34{ 35 local tmp_dir="$1" 36 local mount_img="${tmp_dir}/test.img" 37 local mount_dir="${tmp_dir}/mnt" 38 local copied_bin_path="${mount_dir}/$(basename ${TEST_BINARY})" 39 mkdir -p ${mount_dir} 40 41 dd if=/dev/zero of="${mount_img}" bs=1M count=10 42 43 losetup -f "${mount_img}" 44 local loop_device=$(losetup -a | grep ${mount_img:?} | cut -d ":" -f1) 45 46 mkfs.ext2 "${loop_device:?}" 47 mount "${loop_device}" "${mount_dir}" 48 49 cp "${TEST_BINARY}" "${mount_dir}" 50 local mount_uuid="$(blkid ${loop_device} | sed 's/.*UUID="\([^"]*\)".*/\1/')" 51 52 ensure_mount_securityfs 53 echo "measure func=BPRM_CHECK fsuuid=${mount_uuid}" > ${IMA_POLICY_FILE} 54 echo "measure func=BPRM_CHECK fsuuid=${mount_uuid}" > ${mount_dir}/policy_test 55} 56 57cleanup() { 58 local tmp_dir="$1" 59 local mount_img="${tmp_dir}/test.img" 60 local mount_dir="${tmp_dir}/mnt" 61 62 local loop_devices=$(losetup -a | grep ${mount_img:?} | cut -d ":" -f1) 63 64 for loop_dev in "${loop_devices}"; do 65 losetup -d $loop_dev 66 done 67 68 umount ${mount_dir} 69 rm -rf ${tmp_dir} 70} 71 72run() 73{ 74 local tmp_dir="$1" 75 local mount_dir="${tmp_dir}/mnt" 76 local copied_bin_path="${mount_dir}/$(basename ${TEST_BINARY})" 77 78 exec "${copied_bin_path}" 79} 80 81modify_bin() 82{ 83 local tmp_dir="$1" 84 local mount_dir="${tmp_dir}/mnt" 85 local copied_bin_path="${mount_dir}/$(basename ${TEST_BINARY})" 86 87 echo "mod" >> "${copied_bin_path}" 88} 89 90restore_bin() 91{ 92 local tmp_dir="$1" 93 local mount_dir="${tmp_dir}/mnt" 94 local copied_bin_path="${mount_dir}/$(basename ${TEST_BINARY})" 95 96 truncate -s -4 "${copied_bin_path}" 97} 98 99load_policy() 100{ 101 local tmp_dir="$1" 102 local mount_dir="${tmp_dir}/mnt" 103 104 echo ${mount_dir}/policy_test > ${IMA_POLICY_FILE} 2> /dev/null 105} 106 107catch() 108{ 109 local exit_code="$1" 110 local log_file="$2" 111 112 if [[ "${exit_code}" -ne 0 ]]; then 113 cat "${log_file}" >&3 114 fi 115 116 rm -f "${log_file}" 117 exit ${exit_code} 118} 119 120main() 121{ 122 [[ $# -ne 2 ]] && usage 123 124 local action="$1" 125 local tmp_dir="$2" 126 127 [[ ! -d "${tmp_dir}" ]] && echo "Directory ${tmp_dir} doesn't exist" && exit 1 128 129 if [[ "${action}" == "setup" ]]; then 130 setup "${tmp_dir}" 131 elif [[ "${action}" == "cleanup" ]]; then 132 cleanup "${tmp_dir}" 133 elif [[ "${action}" == "run" ]]; then 134 run "${tmp_dir}" 135 elif [[ "${action}" == "modify-bin" ]]; then 136 modify_bin "${tmp_dir}" 137 elif [[ "${action}" == "restore-bin" ]]; then 138 restore_bin "${tmp_dir}" 139 elif [[ "${action}" == "load-policy" ]]; then 140 load_policy "${tmp_dir}" 141 else 142 echo "Unknown action: ${action}" 143 exit 1 144 fi 145} 146 147trap 'catch "$?" "${LOG_FILE}"' EXIT 148 149if [[ "${VERBOSE}" -eq 0 ]]; then 150 # Save the stderr to 3 so that we can output back to 151 # it incase of an error. 152 exec 3>&2 1>"${LOG_FILE}" 2>&1 153fi 154 155main "$@" 156rm -f "${LOG_FILE}" 157