157 lines · bash
1#!/bin/bash2# SPDX-License-Identifier: GPL-2.03 4set -e5set -u6set -o pipefail7 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 117}18 19ensure_mount_securityfs()20{21 local securityfs_dir=$(grep "securityfs" /proc/mounts | awk '{print $2}')22 23 if [ -z "${securityfs_dir}" ]; then24 securityfs_dir=/sys/kernel/security25 mount -t securityfs security "${securityfs_dir}"26 fi27 28 if [ ! -d "${securityfs_dir}" ]; then29 echo "${securityfs_dir}: securityfs is not mounted" && exit 130 fi31}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=1042 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_securityfs53 echo "measure func=BPRM_CHECK fsuuid=${mount_uuid}" > ${IMA_POLICY_FILE}54 echo "measure func=BPRM_CHECK fsuuid=${mount_uuid}" > ${mount_dir}/policy_test55}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}"; do65 losetup -d $loop_dev66 done67 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/null105}106 107catch()108{109 local exit_code="$1"110 local log_file="$2"111 112 if [[ "${exit_code}" -ne 0 ]]; then113 cat "${log_file}" >&3114 fi115 116 rm -f "${log_file}"117 exit ${exit_code}118}119 120main()121{122 [[ $# -ne 2 ]] && usage123 124 local action="$1"125 local tmp_dir="$2"126 127 [[ ! -d "${tmp_dir}" ]] && echo "Directory ${tmp_dir} doesn't exist" && exit 1128 129 if [[ "${action}" == "setup" ]]; then130 setup "${tmp_dir}"131 elif [[ "${action}" == "cleanup" ]]; then132 cleanup "${tmp_dir}"133 elif [[ "${action}" == "run" ]]; then134 run "${tmp_dir}"135 elif [[ "${action}" == "modify-bin" ]]; then136 modify_bin "${tmp_dir}"137 elif [[ "${action}" == "restore-bin" ]]; then138 restore_bin "${tmp_dir}"139 elif [[ "${action}" == "load-policy" ]]; then140 load_policy "${tmp_dir}"141 else142 echo "Unknown action: ${action}"143 exit 1144 fi145}146 147trap 'catch "$?" "${LOG_FILE}"' EXIT148 149if [[ "${VERBOSE}" -eq 0 ]]; then150 # Save the stderr to 3 so that we can output back to151 # it incase of an error.152 exec 3>&2 1>"${LOG_FILE}" 2>&1153fi154 155main "$@"156rm -f "${LOG_FILE}"157