brintos

brintos / linux-shallow public Read only

0
0
Text · 7.0 KiB · 810b149 Raw
241 lines · c
1// SPDX-License-Identifier: GPL-2.02 3/*4 * Copyright (C) 2020 Google LLC.5 */6 7#include <stdio.h>8#include <stdlib.h>9#include <unistd.h>10#include <sys/wait.h>11#include <test_progs.h>12#include <linux/ring_buffer.h>13 14#include "ima.skel.h"15 16#define MAX_SAMPLES 417 18static int _run_measured_process(const char *measured_dir, u32 *monitored_pid,19				 const char *cmd)20{21	int child_pid, child_status;22 23	child_pid = fork();24	if (child_pid == 0) {25		*monitored_pid = getpid();26		execlp("./ima_setup.sh", "./ima_setup.sh", cmd, measured_dir,27		       NULL);28		exit(errno);29 30	} else if (child_pid > 0) {31		waitpid(child_pid, &child_status, 0);32		return WEXITSTATUS(child_status);33	}34 35	return -EINVAL;36}37 38static int run_measured_process(const char *measured_dir, u32 *monitored_pid)39{40	return _run_measured_process(measured_dir, monitored_pid, "run");41}42 43static u64 ima_hash_from_bpf[MAX_SAMPLES];44static int ima_hash_from_bpf_idx;45 46static int process_sample(void *ctx, void *data, size_t len)47{48	if (ima_hash_from_bpf_idx >= MAX_SAMPLES)49		return -ENOSPC;50 51	ima_hash_from_bpf[ima_hash_from_bpf_idx++] = *((u64 *)data);52	return 0;53}54 55static void test_init(struct ima__bss *bss)56{57	ima_hash_from_bpf_idx = 0;58 59	bss->use_ima_file_hash = false;60	bss->enable_bprm_creds_for_exec = false;61	bss->enable_kernel_read_file = false;62	bss->test_deny = false;63}64 65void test_test_ima(void)66{67	char measured_dir_template[] = "/tmp/ima_measuredXXXXXX";68	struct ring_buffer *ringbuf = NULL;69	const char *measured_dir;70	u64 bin_true_sample;71	char cmd[256];72 73	int err, duration = 0, fresh_digest_idx = 0;74	struct ima *skel = NULL;75 76	skel = ima__open_and_load();77	if (CHECK(!skel, "skel_load", "skeleton failed\n"))78		goto close_prog;79 80	ringbuf = ring_buffer__new(bpf_map__fd(skel->maps.ringbuf),81				   process_sample, NULL, NULL);82	if (!ASSERT_OK_PTR(ringbuf, "ringbuf"))83		goto close_prog;84 85	err = ima__attach(skel);86	if (CHECK(err, "attach", "attach failed: %d\n", err))87		goto close_prog;88 89	measured_dir = mkdtemp(measured_dir_template);90	if (CHECK(measured_dir == NULL, "mkdtemp", "err %d\n", errno))91		goto close_prog;92 93	snprintf(cmd, sizeof(cmd), "./ima_setup.sh setup %s", measured_dir);94	err = system(cmd);95	if (CHECK(err, "failed to run command", "%s, errno = %d\n", cmd, errno))96		goto close_clean;97 98	/*99	 * Test #1100	 * - Goal: obtain a sample with the bpf_ima_inode_hash() helper101	 * - Expected result:  1 sample (/bin/true)102	 */103	test_init(skel->bss);104	err = run_measured_process(measured_dir, &skel->bss->monitored_pid);105	if (CHECK(err, "run_measured_process #1", "err = %d\n", err))106		goto close_clean;107 108	err = ring_buffer__consume(ringbuf);109	ASSERT_EQ(err, 1, "num_samples_or_err");110	ASSERT_NEQ(ima_hash_from_bpf[0], 0, "ima_hash");111 112	/*113	 * Test #2114	 * - Goal: obtain samples with the bpf_ima_file_hash() helper115	 * - Expected result: 2 samples (./ima_setup.sh, /bin/true)116	 */117	test_init(skel->bss);118	skel->bss->use_ima_file_hash = true;119	err = run_measured_process(measured_dir, &skel->bss->monitored_pid);120	if (CHECK(err, "run_measured_process #2", "err = %d\n", err))121		goto close_clean;122 123	err = ring_buffer__consume(ringbuf);124	ASSERT_EQ(err, 2, "num_samples_or_err");125	ASSERT_NEQ(ima_hash_from_bpf[0], 0, "ima_hash");126	ASSERT_NEQ(ima_hash_from_bpf[1], 0, "ima_hash");127	bin_true_sample = ima_hash_from_bpf[1];128 129	/*130	 * Test #3131	 * - Goal: confirm that bpf_ima_inode_hash() returns a non-fresh digest132	 * - Expected result:133	 *   1 sample (/bin/true: fresh) if commit 62622dab0a28 applied134	 *   2 samples (/bin/true: non-fresh, fresh) if commit 62622dab0a28 is135	 *     not applied136	 *137	 * If commit 62622dab0a28 ("ima: return IMA digest value only when138	 * IMA_COLLECTED flag is set") is applied, bpf_ima_inode_hash() refuses139	 * to give a non-fresh digest, hence the correct result is 1 instead of140	 * 2.141	 */142	test_init(skel->bss);143 144	err = _run_measured_process(measured_dir, &skel->bss->monitored_pid,145				    "modify-bin");146	if (CHECK(err, "modify-bin #3", "err = %d\n", err))147		goto close_clean;148 149	skel->bss->enable_bprm_creds_for_exec = true;150	err = run_measured_process(measured_dir, &skel->bss->monitored_pid);151	if (CHECK(err, "run_measured_process #3", "err = %d\n", err))152		goto close_clean;153 154	err = ring_buffer__consume(ringbuf);155	ASSERT_GE(err, 1, "num_samples_or_err");156	if (err == 2) {157		ASSERT_NEQ(ima_hash_from_bpf[0], 0, "ima_hash");158		ASSERT_EQ(ima_hash_from_bpf[0], bin_true_sample,159			  "sample_equal_or_err");160		fresh_digest_idx = 1;161	}162 163	ASSERT_NEQ(ima_hash_from_bpf[fresh_digest_idx], 0, "ima_hash");164	/* IMA refreshed the digest. */165	ASSERT_NEQ(ima_hash_from_bpf[fresh_digest_idx], bin_true_sample,166		   "sample_equal_or_err");167 168	/*169	 * Test #4170	 * - Goal: verify that bpf_ima_file_hash() returns a fresh digest171	 * - Expected result: 4 samples (./ima_setup.sh: fresh, fresh;172	 *                               /bin/true: fresh, fresh)173	 */174	test_init(skel->bss);175	skel->bss->use_ima_file_hash = true;176	skel->bss->enable_bprm_creds_for_exec = true;177	err = run_measured_process(measured_dir, &skel->bss->monitored_pid);178	if (CHECK(err, "run_measured_process #4", "err = %d\n", err))179		goto close_clean;180 181	err = ring_buffer__consume(ringbuf);182	ASSERT_EQ(err, 4, "num_samples_or_err");183	ASSERT_NEQ(ima_hash_from_bpf[0], 0, "ima_hash");184	ASSERT_NEQ(ima_hash_from_bpf[1], 0, "ima_hash");185	ASSERT_NEQ(ima_hash_from_bpf[2], 0, "ima_hash");186	ASSERT_NEQ(ima_hash_from_bpf[3], 0, "ima_hash");187	ASSERT_NEQ(ima_hash_from_bpf[2], bin_true_sample,188		   "sample_different_or_err");189	ASSERT_EQ(ima_hash_from_bpf[3], ima_hash_from_bpf[2],190		  "sample_equal_or_err");191 192	skel->bss->use_ima_file_hash = false;193	skel->bss->enable_bprm_creds_for_exec = false;194	err = _run_measured_process(measured_dir, &skel->bss->monitored_pid,195				    "restore-bin");196	if (CHECK(err, "restore-bin #3", "err = %d\n", err))197		goto close_clean;198 199	/*200	 * Test #5201	 * - Goal: obtain a sample from the kernel_read_file hook202	 * - Expected result: 2 samples (./ima_setup.sh, policy_test)203	 */204	test_init(skel->bss);205	skel->bss->use_ima_file_hash = true;206	skel->bss->enable_kernel_read_file = true;207	err = _run_measured_process(measured_dir, &skel->bss->monitored_pid,208				    "load-policy");209	if (CHECK(err, "run_measured_process #5", "err = %d\n", err))210		goto close_clean;211 212	err = ring_buffer__consume(ringbuf);213	ASSERT_EQ(err, 2, "num_samples_or_err");214	ASSERT_NEQ(ima_hash_from_bpf[0], 0, "ima_hash");215	ASSERT_NEQ(ima_hash_from_bpf[1], 0, "ima_hash");216 217	/*218	 * Test #6219	 * - Goal: ensure that the kernel_read_file hook denies an operation220	 * - Expected result: 0 samples221	 */222	test_init(skel->bss);223	skel->bss->enable_kernel_read_file = true;224	skel->bss->test_deny = true;225	err = _run_measured_process(measured_dir, &skel->bss->monitored_pid,226				    "load-policy");227	if (CHECK(!err, "run_measured_process #6", "err = %d\n", err))228		goto close_clean;229 230	err = ring_buffer__consume(ringbuf);231	ASSERT_EQ(err, 0, "num_samples_or_err");232 233close_clean:234	snprintf(cmd, sizeof(cmd), "./ima_setup.sh cleanup %s", measured_dir);235	err = system(cmd);236	CHECK(err, "failed to run command", "%s, errno = %d\n", cmd, errno);237close_prog:238	ring_buffer__free(ringbuf);239	ima__destroy(skel);240}241