Some kernels builds might inline vfs_getattr call within fstat syscall code path, so fentry/vfs_getattr trampoline is not called. Add security_inode_getattr to allowlist and switch the d_path test stat trampoline to security_inode_getattr. Keeping dentry_open and filp_close, because they are in their own files, so unlikely to be inlined, but in case they are, adding security_file_open. Adding flags that indicate trampolines were called and failing the test if any of them got missed, so it's easier to identify the issue next time.
Unified · Split
| @@ -1114,6 +1114,14 @@ BPF_CALL_3(bpf_d_path, struct path *, path, char *, buf, u32, sz) · 1113 unmodified lines | ||
| 1114 | 1114 | } |
| 1115 | 1115 | |
| 1116 | 1116 | BTF_SET_START(btf_allowlist_d_path) |
| 1117 | +#ifdef CONFIG_SECURITY | |
| 1118 | +BTF_ID(func, security_file_permission) | |
| 1119 | +BTF_ID(func, security_inode_getattr) | |
| 1120 | +BTF_ID(func, security_file_open) | |
| 1121 | +#endif | |
| 1122 | +#ifdef CONFIG_SECURITY_PATH | |
| 1123 | +BTF_ID(func, security_path_truncate) | |
| 1124 | +#endif | |
| 1117 | 1125 | BTF_ID(func, vfs_truncate) |
| 1118 | 1126 | BTF_ID(func, vfs_fallocate) |
| 1119 | 1127 | BTF_ID(func, dentry_open) |
| @@ -120,6 +120,16 @@ void test_d_path(void) · 119 unmodified lines | ||
| 120 | 120 | if (err < 0) |
| 121 | 121 | goto cleanup; |
| 122 | 122 | |
| 123 | + if (CHECK(!bss->called_stat, | |
| 124 | + "stat", | |
| 125 | + "trampoline for security_inode_getattr was not called\n")) | |
| 126 | + goto cleanup; | |
| 127 | + | |
| 128 | + if (CHECK(!bss->called_close, | |
| 129 | + "close", | |
| 130 | + "trampoline for filp_close was not called\n")) | |
| 131 | + goto cleanup; | |
| 132 | + | |
| 123 | 133 | for (int i = 0; i < MAX_FILES; i++) { |
| 124 | 134 | CHECK(strncmp(src.paths[i], bss->paths_stat[i], MAX_PATH_LEN), |
| 125 | 135 | "check", |
| @@ -15,7 +15,10 @@ char paths_close[MAX_FILES][MAX_PATH_LEN] = {}; · 14 unmodified lines | ||
| 15 | 15 | int rets_stat[MAX_FILES] = {}; |
| 16 | 16 | int rets_close[MAX_FILES] = {}; |
| 17 | 17 | |
| 18 | −SEC("fentry/vfs_getattr") | |
| 18 | +int called_stat = 0; | |
| 19 | +int called_close = 0; | |
| 20 | + | |
| 21 | +SEC("fentry/security_inode_getattr") | |
| 19 | 22 | int BPF_PROG(prog_stat, struct path *path, struct kstat *stat, |
| 20 | 23 | __u32 request_mask, unsigned int query_flags) |
| 21 | 24 | { |
| @@ -23,6 +26,8 @@ int BPF_PROG(prog_stat, struct path *path, struct kstat *stat, · 1 unmodified line | ||
| 23 | 26 | __u32 cnt = cnt_stat; |
| 24 | 27 | int ret; |
| 25 | 28 | |
| 29 | + called_stat = 1; | |
| 30 | + | |
| 26 | 31 | if (pid != my_pid) |
| 27 | 32 | return 0; |
| 28 | 33 | |
| @@ -42,6 +47,8 @@ int BPF_PROG(prog_close, struct file *file, void *id) · 13 unmodified lines | ||
| 42 | 47 | __u32 cnt = cnt_close; |
| 43 | 48 | int ret; |
| 44 | 49 | |
| 50 | + called_close = 1; | |
| 51 | + | |
| 45 | 52 | if (pid != my_pid) |
| 46 | 53 | return 0; |
| 47 | 54 | |