forked from unixbhaskar/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
bpf: Add a selftest for bpf_ima_inode_hash
The test does the following: - Mounts a loopback filesystem and appends the IMA policy to measure executions only on this file-system. Restricting the IMA policy to a particular filesystem prevents a system-wide IMA policy change. - Executes an executable copied to this loopback filesystem. - Calls the bpf_ima_inode_hash in the bprm_committed_creds hook and checks if the call succeeded and checks if a hash was calculated. The test shells out to the added ima_setup.sh script as the setup is better handled in a shell script and is more complicated to do in the test program or even shelling out individual commands from C. The list of required configs (i.e. IMA, SECURITYFS, IMA_{WRITE,READ}_POLICY) for running this test are also updated. Suggested-by: Mimi Zohar <[email protected]> (limit policy rule to loopback mount) Signed-off-by: KP Singh <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]> Acked-by: Yonghong Song <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
- Loading branch information
Showing
4 changed files
with
186 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
#!/bin/bash | ||
# SPDX-License-Identifier: GPL-2.0 | ||
|
||
set -e | ||
set -u | ||
|
||
IMA_POLICY_FILE="/sys/kernel/security/ima/policy" | ||
TEST_BINARY="/bin/true" | ||
|
||
usage() | ||
{ | ||
echo "Usage: $0 <setup|cleanup|run> <existing_tmp_dir>" | ||
exit 1 | ||
} | ||
|
||
setup() | ||
{ | ||
local tmp_dir="$1" | ||
local mount_img="${tmp_dir}/test.img" | ||
local mount_dir="${tmp_dir}/mnt" | ||
local copied_bin_path="${mount_dir}/$(basename ${TEST_BINARY})" | ||
mkdir -p ${mount_dir} | ||
|
||
dd if=/dev/zero of="${mount_img}" bs=1M count=10 | ||
|
||
local loop_device="$(losetup --find --show ${mount_img})" | ||
|
||
mkfs.ext4 "${loop_device}" | ||
mount "${loop_device}" "${mount_dir}" | ||
|
||
cp "${TEST_BINARY}" "${mount_dir}" | ||
local mount_uuid="$(blkid -s UUID -o value ${loop_device})" | ||
echo "measure func=BPRM_CHECK fsuuid=${mount_uuid}" > ${IMA_POLICY_FILE} | ||
} | ||
|
||
cleanup() { | ||
local tmp_dir="$1" | ||
local mount_img="${tmp_dir}/test.img" | ||
local mount_dir="${tmp_dir}/mnt" | ||
|
||
local loop_devices=$(losetup -j ${mount_img} -O NAME --noheadings) | ||
for loop_dev in "${loop_devices}"; do | ||
losetup -d $loop_dev | ||
done | ||
|
||
umount ${mount_dir} | ||
rm -rf ${tmp_dir} | ||
} | ||
|
||
run() | ||
{ | ||
local tmp_dir="$1" | ||
local mount_dir="${tmp_dir}/mnt" | ||
local copied_bin_path="${mount_dir}/$(basename ${TEST_BINARY})" | ||
|
||
exec "${copied_bin_path}" | ||
} | ||
|
||
main() | ||
{ | ||
[[ $# -ne 2 ]] && usage | ||
|
||
local action="$1" | ||
local tmp_dir="$2" | ||
|
||
[[ ! -d "${tmp_dir}" ]] && echo "Directory ${tmp_dir} doesn't exist" && exit 1 | ||
|
||
if [[ "${action}" == "setup" ]]; then | ||
setup "${tmp_dir}" | ||
elif [[ "${action}" == "cleanup" ]]; then | ||
cleanup "${tmp_dir}" | ||
elif [[ "${action}" == "run" ]]; then | ||
run "${tmp_dir}" | ||
else | ||
echo "Unknown action: ${action}" | ||
exit 1 | ||
fi | ||
} | ||
|
||
main "$@" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
|
||
/* | ||
* Copyright (C) 2020 Google LLC. | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <unistd.h> | ||
#include <sys/wait.h> | ||
#include <test_progs.h> | ||
|
||
#include "ima.skel.h" | ||
|
||
static int run_measured_process(const char *measured_dir, u32 *monitored_pid) | ||
{ | ||
int child_pid, child_status; | ||
|
||
child_pid = fork(); | ||
if (child_pid == 0) { | ||
*monitored_pid = getpid(); | ||
execlp("./ima_setup.sh", "./ima_setup.sh", "run", measured_dir, | ||
NULL); | ||
exit(errno); | ||
|
||
} else if (child_pid > 0) { | ||
waitpid(child_pid, &child_status, 0); | ||
return WEXITSTATUS(child_status); | ||
} | ||
|
||
return -EINVAL; | ||
} | ||
|
||
void test_test_ima(void) | ||
{ | ||
char measured_dir_template[] = "/tmp/ima_measuredXXXXXX"; | ||
const char *measured_dir; | ||
char cmd[256]; | ||
|
||
int err, duration = 0; | ||
struct ima *skel = NULL; | ||
|
||
skel = ima__open_and_load(); | ||
if (CHECK(!skel, "skel_load", "skeleton failed\n")) | ||
goto close_prog; | ||
|
||
err = ima__attach(skel); | ||
if (CHECK(err, "attach", "attach failed: %d\n", err)) | ||
goto close_prog; | ||
|
||
measured_dir = mkdtemp(measured_dir_template); | ||
if (CHECK(measured_dir == NULL, "mkdtemp", "err %d\n", errno)) | ||
goto close_prog; | ||
|
||
snprintf(cmd, sizeof(cmd), "./ima_setup.sh setup %s", measured_dir); | ||
if (CHECK_FAIL(system(cmd))) | ||
goto close_clean; | ||
|
||
err = run_measured_process(measured_dir, &skel->bss->monitored_pid); | ||
if (CHECK(err, "run_measured_process", "err = %d\n", err)) | ||
goto close_clean; | ||
|
||
CHECK(skel->data->ima_hash_ret < 0, "ima_hash_ret", | ||
"ima_hash_ret = %ld\n", skel->data->ima_hash_ret); | ||
|
||
CHECK(skel->bss->ima_hash == 0, "ima_hash", | ||
"ima_hash = %lu\n", skel->bss->ima_hash); | ||
|
||
close_clean: | ||
snprintf(cmd, sizeof(cmd), "./ima_setup.sh cleanup %s", measured_dir); | ||
CHECK_FAIL(system(cmd)); | ||
close_prog: | ||
ima__destroy(skel); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
|
||
/* | ||
* Copyright 2020 Google LLC. | ||
*/ | ||
|
||
#include "vmlinux.h" | ||
#include <errno.h> | ||
#include <bpf/bpf_helpers.h> | ||
#include <bpf/bpf_tracing.h> | ||
|
||
long ima_hash_ret = -1; | ||
u64 ima_hash = 0; | ||
u32 monitored_pid = 0; | ||
|
||
char _license[] SEC("license") = "GPL"; | ||
|
||
SEC("lsm.s/bprm_committed_creds") | ||
int BPF_PROG(ima, struct linux_binprm *bprm) | ||
{ | ||
u32 pid = bpf_get_current_pid_tgid() >> 32; | ||
|
||
if (pid == monitored_pid) | ||
ima_hash_ret = bpf_ima_inode_hash(bprm->file->f_inode, | ||
&ima_hash, sizeof(ima_hash)); | ||
|
||
return 0; | ||
} |