Skip to content

Commit ebdd435

Browse files
electronlsrKernel Patches Daemon
authored andcommitted
selftests/bpf: add regression test for bpf_d_path()
Add a simple LSM BPF program and a corresponding test_progs test case to exercise bpf_d_path() and ensure that prefix comparisons on the returned path keep working. The LSM program hooks bprm_check_security, calls bpf_d_path() on the binary being executed, and compares the returned path against the "/tmp/" prefix. The result is recorded in an array map. The user space test runs /tmp/bpf_d_path_test (copied from /bin/true) and checks that the BPF program records a successful prefix match. Without the preceding fix to bpf_d_path()'s helper prototype, the test can fail due to the verifier incorrectly assuming that the buffer contents are unchanged across the helper call and misoptimizing the program. With the fix applied, the test passes. Co-developed-by: Zesen Liu <[email protected]> Signed-off-by: Zesen Liu <[email protected]> Co-developed-by: Peili Gao <[email protected]> Signed-off-by: Peili Gao <[email protected]> Co-developed-by: Haoran Ni <[email protected]> Signed-off-by: Haoran Ni <[email protected]> Signed-off-by: Shuran Liu <[email protected]>
1 parent 29502d8 commit ebdd435

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
#include <test_progs.h>
3+
#include "d_path_lsm.skel.h"
4+
5+
void test_d_path_lsm(void)
6+
{
7+
struct d_path_lsm *skel = NULL;
8+
int err, map_fd, key = 0, val = 0;
9+
10+
skel = d_path_lsm__open_and_load();
11+
if (!ASSERT_OK_PTR(skel, "open_and_load"))
12+
return;
13+
14+
err = d_path_lsm__attach(skel);
15+
if (!ASSERT_OK(err, "attach"))
16+
goto out;
17+
18+
system("cp /bin/true /tmp/bpf_d_path_test 2>/dev/null || :");
19+
system("/tmp/bpf_d_path_test >/dev/null 2>&1");
20+
21+
map_fd = bpf_map__fd(skel->maps.result);
22+
err = bpf_map_lookup_elem(map_fd, &key, &val);
23+
ASSERT_OK(err, "lookup_result");
24+
ASSERT_EQ(val, 1, "prefix_match");
25+
out:
26+
d_path_lsm__destroy(skel);
27+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
#include "vmlinux.h"
3+
#include <bpf/bpf_helpers.h>
4+
#include <bpf/bpf_tracing.h>
5+
6+
char LICENSE[] SEC("license") = "GPL";
7+
8+
#define FILENAME_MAX_SIZE 256
9+
#define TARGET_DIR "/tmp/"
10+
#define TARGET_DIR_LEN 5
11+
12+
struct {
13+
__uint(type, BPF_MAP_TYPE_ARRAY);
14+
__uint(max_entries, 1);
15+
__type(key, int);
16+
__type(value, int);
17+
} result SEC(".maps");
18+
19+
SEC("lsm/bprm_check_security")
20+
int BPF_PROG(d_path_lsm_prog, struct linux_binprm *bprm)
21+
{
22+
char path[FILENAME_MAX_SIZE] = {};
23+
long len;
24+
int key = 0;
25+
int val = 0;
26+
27+
len = bpf_d_path(&bprm->file->f_path, path, sizeof(path));
28+
if (len < 0)
29+
return 0;
30+
31+
#pragma unroll
32+
for (int i = 0; i < TARGET_DIR_LEN; i++) {
33+
if ((u8)path[i] != (u8)TARGET_DIR[i]) {
34+
val = -1; /* mismatch */
35+
bpf_map_update_elem(&result, &key, &val, BPF_ANY);
36+
return 0;
37+
}
38+
}
39+
40+
val = 1; /* prefix match */
41+
bpf_map_update_elem(&result, &key, &val, BPF_ANY);
42+
return 0;
43+
}

0 commit comments

Comments
 (0)