0001
0002
0003
0004 set -e
0005 set -u
0006 set -o pipefail
0007
0008 IMA_POLICY_FILE="/sys/kernel/security/ima/policy"
0009 TEST_BINARY="/bin/true"
0010 VERBOSE="${SELFTESTS_VERBOSE:=0}"
0011 LOG_FILE="$(mktemp /tmp/ima_setup.XXXX.log)"
0012
0013 usage()
0014 {
0015 echo "Usage: $0 <setup|cleanup|run|modify-bin|restore-bin|load-policy> <existing_tmp_dir>"
0016 exit 1
0017 }
0018
0019 ensure_mount_securityfs()
0020 {
0021 local securityfs_dir=$(grep "securityfs" /proc/mounts | awk '{print $2}')
0022
0023 if [ -z "${securityfs_dir}" ]; then
0024 securityfs_dir=/sys/kernel/security
0025 mount -t securityfs security "${securityfs_dir}"
0026 fi
0027
0028 if [ ! -d "${securityfs_dir}" ]; then
0029 echo "${securityfs_dir}: securityfs is not mounted" && exit 1
0030 fi
0031 }
0032
0033 setup()
0034 {
0035 local tmp_dir="$1"
0036 local mount_img="${tmp_dir}/test.img"
0037 local mount_dir="${tmp_dir}/mnt"
0038 local copied_bin_path="${mount_dir}/$(basename ${TEST_BINARY})"
0039 mkdir -p ${mount_dir}
0040
0041 dd if=/dev/zero of="${mount_img}" bs=1M count=10
0042
0043 losetup -f "${mount_img}"
0044 local loop_device=$(losetup -a | grep ${mount_img:?} | cut -d ":" -f1)
0045
0046 mkfs.ext2 "${loop_device:?}"
0047 mount "${loop_device}" "${mount_dir}"
0048
0049 cp "${TEST_BINARY}" "${mount_dir}"
0050 local mount_uuid="$(blkid ${loop_device} | sed 's/.*UUID="\([^"]*\)".*/\1/')"
0051
0052 ensure_mount_securityfs
0053 echo "measure func=BPRM_CHECK fsuuid=${mount_uuid}" > ${IMA_POLICY_FILE}
0054 echo "measure func=BPRM_CHECK fsuuid=${mount_uuid}" > ${mount_dir}/policy_test
0055 }
0056
0057 cleanup() {
0058 local tmp_dir="$1"
0059 local mount_img="${tmp_dir}/test.img"
0060 local mount_dir="${tmp_dir}/mnt"
0061
0062 local loop_devices=$(losetup -a | grep ${mount_img:?} | cut -d ":" -f1)
0063
0064 for loop_dev in "${loop_devices}"; do
0065 losetup -d $loop_dev
0066 done
0067
0068 umount ${mount_dir}
0069 rm -rf ${tmp_dir}
0070 }
0071
0072 run()
0073 {
0074 local tmp_dir="$1"
0075 local mount_dir="${tmp_dir}/mnt"
0076 local copied_bin_path="${mount_dir}/$(basename ${TEST_BINARY})"
0077
0078 exec "${copied_bin_path}"
0079 }
0080
0081 modify_bin()
0082 {
0083 local tmp_dir="$1"
0084 local mount_dir="${tmp_dir}/mnt"
0085 local copied_bin_path="${mount_dir}/$(basename ${TEST_BINARY})"
0086
0087 echo "mod" >> "${copied_bin_path}"
0088 }
0089
0090 restore_bin()
0091 {
0092 local tmp_dir="$1"
0093 local mount_dir="${tmp_dir}/mnt"
0094 local copied_bin_path="${mount_dir}/$(basename ${TEST_BINARY})"
0095
0096 truncate -s -4 "${copied_bin_path}"
0097 }
0098
0099 load_policy()
0100 {
0101 local tmp_dir="$1"
0102 local mount_dir="${tmp_dir}/mnt"
0103
0104 echo ${mount_dir}/policy_test > ${IMA_POLICY_FILE} 2> /dev/null
0105 }
0106
0107 catch()
0108 {
0109 local exit_code="$1"
0110 local log_file="$2"
0111
0112 if [[ "${exit_code}" -ne 0 ]]; then
0113 cat "${log_file}" >&3
0114 fi
0115
0116 rm -f "${log_file}"
0117 exit ${exit_code}
0118 }
0119
0120 main()
0121 {
0122 [[ $# -ne 2 ]] && usage
0123
0124 local action="$1"
0125 local tmp_dir="$2"
0126
0127 [[ ! -d "${tmp_dir}" ]] && echo "Directory ${tmp_dir} doesn't exist" && exit 1
0128
0129 if [[ "${action}" == "setup" ]]; then
0130 setup "${tmp_dir}"
0131 elif [[ "${action}" == "cleanup" ]]; then
0132 cleanup "${tmp_dir}"
0133 elif [[ "${action}" == "run" ]]; then
0134 run "${tmp_dir}"
0135 elif [[ "${action}" == "modify-bin" ]]; then
0136 modify_bin "${tmp_dir}"
0137 elif [[ "${action}" == "restore-bin" ]]; then
0138 restore_bin "${tmp_dir}"
0139 elif [[ "${action}" == "load-policy" ]]; then
0140 load_policy "${tmp_dir}"
0141 else
0142 echo "Unknown action: ${action}"
0143 exit 1
0144 fi
0145 }
0146
0147 trap 'catch "$?" "${LOG_FILE}"' EXIT
0148
0149 if [[ "${VERBOSE}" -eq 0 ]]; then
0150 # Save the stderr to 3 so that we can output back to
0151 # it incase of an error.
0152 exec 3>&2 1>"${LOG_FILE}" 2>&1
0153 fi
0154
0155 main "$@"
0156 rm -f "${LOG_FILE}"