Message ID | AM6PR03MB5080E0DFE4F9BAFFDB9D113B99042@AM6PR03MB5080.eurprd03.prod.outlook.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | bpf: Add open-coded style process file iterator and bpf_fget_task() kfunc | expand |
On Tue, Dec 17, 2024 at 3:45 PM Juntong Deng <juntong.deng@outlook.com> wrote: > > -static int bpf_fs_kfuncs_filter(const struct bpf_prog *prog, u32 kfunc_id) > -{ > - if (!btf_id_set8_contains(&bpf_fs_kfunc_set_ids, kfunc_id) || > - prog->type == BPF_PROG_TYPE_LSM) > - return 0; > - return -EACCES; > -} > - > static const struct btf_kfunc_id_set bpf_fs_kfunc_set = { > .owner = THIS_MODULE, > .set = &bpf_fs_kfunc_set_ids, > - .filter = bpf_fs_kfuncs_filter, > }; > > static int __init bpf_fs_kfuncs_init(void) > { > - return register_btf_kfunc_id_set(BPF_PROG_TYPE_LSM, &bpf_fs_kfunc_set); > + int ret; > + > + ret = register_btf_kfunc_id_set(BPF_PROG_TYPE_LSM, &bpf_fs_kfunc_set); > + return ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &bpf_fs_kfunc_set); > } > > late_initcall(bpf_fs_kfuncs_init); > diff --git a/tools/testing/selftests/bpf/progs/verifier_vfs_reject.c b/tools/testing/selftests/bpf/progs/verifier_vfs_reject.c > index d6d3f4fcb24c..5aab75fd2fa5 100644 > --- a/tools/testing/selftests/bpf/progs/verifier_vfs_reject.c > +++ b/tools/testing/selftests/bpf/progs/verifier_vfs_reject.c > @@ -148,14 +148,4 @@ int BPF_PROG(path_d_path_kfunc_invalid_buf_sz, struct file *file) > return 0; > } > > -SEC("fentry/vfs_open") > -__failure __msg("calling kernel function bpf_path_d_path is not allowed") This is incorrect. You have to keep bpf_fs_kfuncs_filter() and prog->type == BPF_PROG_TYPE_LSM check because bpf_prog_type_to_kfunc_hook() aliases LSM and fentry into BTF_KFUNC_HOOK_TRACING category. It's been an annoying quirk. We're figuring out details for significant refactoring of register_btf_kfunc_id_set() and the whole registration process. Maybe you would be interested in working on it? The main goal is to get rid of run-time mask check in SCX_CALL_OP() and make it static by the verifier. To make that happen scx_kf_mask flags would need to become KF_* flags while each struct-ops callback will specify the expected mask. Then at struct-ops prog attach time the verifier will see the expected mask and can check that all kfuncs calls of this particular program satisfy the mask. Then all of the runtime overhead of current->scx.kf_mask and scx_kf_allowed() will go away.
diff --git a/fs/bpf_fs_kfuncs.c b/fs/bpf_fs_kfuncs.c index 4a810046dcf3..6010fccc9db8 100644 --- a/fs/bpf_fs_kfuncs.c +++ b/fs/bpf_fs_kfuncs.c @@ -26,8 +26,6 @@ __bpf_kfunc_start_defs(); * acquired by this BPF kfunc will result in the BPF program being rejected by * the BPF verifier. * - * This BPF kfunc may only be called from BPF LSM programs. - * * Internally, this BPF kfunc leans on get_task_exe_file(), such that calling * bpf_get_task_exe_file() would be analogous to calling get_task_exe_file() * directly in kernel context. @@ -49,8 +47,6 @@ __bpf_kfunc struct file *bpf_get_task_exe_file(struct task_struct *task) * passed to this BPF kfunc. Attempting to pass an unreferenced file pointer, or * any other arbitrary pointer for that matter, will result in the BPF program * being rejected by the BPF verifier. - * - * This BPF kfunc may only be called from BPF LSM programs. */ __bpf_kfunc void bpf_put_file(struct file *file) { @@ -70,8 +66,6 @@ __bpf_kfunc void bpf_put_file(struct file *file) * reference, or else the BPF program will be outright rejected by the BPF * verifier. * - * This BPF kfunc may only be called from BPF LSM programs. - * * Return: A positive integer corresponding to the length of the resolved * pathname in *buf*, including the NUL termination character. On error, a * negative integer is returned. @@ -181,23 +175,17 @@ BTF_ID_FLAGS(func, bpf_get_file_xattr, KF_SLEEPABLE | KF_TRUSTED_ARGS) BTF_ID_FLAGS(func, bpf_fget_task, KF_ACQUIRE | KF_TRUSTED_ARGS | KF_RET_NULL) BTF_KFUNCS_END(bpf_fs_kfunc_set_ids) -static int bpf_fs_kfuncs_filter(const struct bpf_prog *prog, u32 kfunc_id) -{ - if (!btf_id_set8_contains(&bpf_fs_kfunc_set_ids, kfunc_id) || - prog->type == BPF_PROG_TYPE_LSM) - return 0; - return -EACCES; -} - static const struct btf_kfunc_id_set bpf_fs_kfunc_set = { .owner = THIS_MODULE, .set = &bpf_fs_kfunc_set_ids, - .filter = bpf_fs_kfuncs_filter, }; static int __init bpf_fs_kfuncs_init(void) { - return register_btf_kfunc_id_set(BPF_PROG_TYPE_LSM, &bpf_fs_kfunc_set); + int ret; + + ret = register_btf_kfunc_id_set(BPF_PROG_TYPE_LSM, &bpf_fs_kfunc_set); + return ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &bpf_fs_kfunc_set); } late_initcall(bpf_fs_kfuncs_init); diff --git a/tools/testing/selftests/bpf/progs/verifier_vfs_reject.c b/tools/testing/selftests/bpf/progs/verifier_vfs_reject.c index d6d3f4fcb24c..5aab75fd2fa5 100644 --- a/tools/testing/selftests/bpf/progs/verifier_vfs_reject.c +++ b/tools/testing/selftests/bpf/progs/verifier_vfs_reject.c @@ -148,14 +148,4 @@ int BPF_PROG(path_d_path_kfunc_invalid_buf_sz, struct file *file) return 0; } -SEC("fentry/vfs_open") -__failure __msg("calling kernel function bpf_path_d_path is not allowed") -int BPF_PROG(path_d_path_kfunc_non_lsm, struct path *path, struct file *f) -{ - /* Calling bpf_path_d_path() from a non-LSM BPF program isn't permitted. - */ - bpf_path_d_path(path, buf, sizeof(buf)); - return 0; -} - char _license[] SEC("license") = "GPL";
Currently fs kfuncs are only available for LSM program type, but fs kfuncs are generic and useful for scenarios other than LSM. This patch makes fs kfuncs available for SYSCALL program type. Signed-off-by: Juntong Deng <juntong.deng@outlook.com> --- fs/bpf_fs_kfuncs.c | 20 ++++--------------- .../selftests/bpf/progs/verifier_vfs_reject.c | 10 ---------- 2 files changed, 4 insertions(+), 26 deletions(-)