Skip to content

Commit

Permalink
bpf/selftests: Update the IMA test to use BPF ring buffer
Browse files Browse the repository at this point in the history
Instead of using shared global variables between userspace and BPF, use
the ring buffer to send the IMA hash on the BPF ring buffer. This helps
in validating both IMA and the usage of the ringbuffer in sleepable
programs.

Signed-off-by: KP Singh <kpsingh@kernel.org>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20210204193622.3367275-3-kpsingh@kernel.org
  • Loading branch information
KP Singh authored and Andrii Nakryiko committed Feb 5, 2021
1 parent ba90c2c commit f446b57
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 13 deletions.
23 changes: 18 additions & 5 deletions tools/testing/selftests/bpf/prog_tests/test_ima.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <unistd.h>
#include <sys/wait.h>
#include <test_progs.h>
#include <linux/ring_buffer.h>

#include "ima.skel.h"

Expand All @@ -31,9 +32,18 @@ static int run_measured_process(const char *measured_dir, u32 *monitored_pid)
return -EINVAL;
}

static u64 ima_hash_from_bpf;

static int process_sample(void *ctx, void *data, size_t len)
{
ima_hash_from_bpf = *((u64 *)data);
return 0;
}

void test_test_ima(void)
{
char measured_dir_template[] = "/tmp/ima_measuredXXXXXX";
struct ring_buffer *ringbuf;
const char *measured_dir;
char cmd[256];

Expand All @@ -44,6 +54,11 @@ void test_test_ima(void)
if (CHECK(!skel, "skel_load", "skeleton failed\n"))
goto close_prog;

ringbuf = ring_buffer__new(bpf_map__fd(skel->maps.ringbuf),
process_sample, NULL, NULL);
if (!ASSERT_OK_PTR(ringbuf, "ringbuf"))
goto close_prog;

err = ima__attach(skel);
if (CHECK(err, "attach", "attach failed: %d\n", err))
goto close_prog;
Expand All @@ -60,11 +75,9 @@ void test_test_ima(void)
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);
err = ring_buffer__consume(ringbuf);
ASSERT_EQ(err, 1, "num_samples_or_err");
ASSERT_NEQ(ima_hash_from_bpf, 0, "ima_hash");

close_clean:
snprintf(cmd, sizeof(cmd), "./ima_setup.sh cleanup %s", measured_dir);
Expand Down
33 changes: 25 additions & 8 deletions tools/testing/selftests/bpf/progs/ima.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,37 @@
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>

long ima_hash_ret = -1;
u64 ima_hash = 0;
u32 monitored_pid = 0;

struct {
__uint(type, BPF_MAP_TYPE_RINGBUF);
__uint(max_entries, 1 << 12);
} ringbuf SEC(".maps");

char _license[] SEC("license") = "GPL";

SEC("lsm.s/bprm_committed_creds")
int BPF_PROG(ima, struct linux_binprm *bprm)
void BPF_PROG(ima, struct linux_binprm *bprm)
{
u32 pid = bpf_get_current_pid_tgid() >> 32;
u64 ima_hash = 0;
u64 *sample;
int ret;
u32 pid;

pid = bpf_get_current_pid_tgid() >> 32;
if (pid == monitored_pid) {
ret = bpf_ima_inode_hash(bprm->file->f_inode, &ima_hash,
sizeof(ima_hash));
if (ret < 0 || ima_hash == 0)
return;

sample = bpf_ringbuf_reserve(&ringbuf, sizeof(u64), 0);
if (!sample)
return;

if (pid == monitored_pid)
ima_hash_ret = bpf_ima_inode_hash(bprm->file->f_inode,
&ima_hash, sizeof(ima_hash));
*sample = ima_hash;
bpf_ringbuf_submit(sample, 0);
}

return 0;
return;
}

0 comments on commit f446b57

Please sign in to comment.