* [PATCH bpf-next v5 0/2] bpf: expand bpf_d_path helper allowlist @ 2021-07-27 13:25 Hengqi Chen 2021-07-27 13:25 ` [PATCH bpf-next v5 1/2] tools/resolve_btfids: emit warnings and patch zero id for missing symbols Hengqi Chen 2021-07-27 13:25 ` [PATCH bpf-next v5 2/2] bpf: expose bpf_d_path helper to vfs_* and security_* functions Hengqi Chen 0 siblings, 2 replies; 7+ messages in thread From: Hengqi Chen @ 2021-07-27 13:25 UTC (permalink / raw) To: bpf Cc: ast, daniel, andrii, yhs, john.fastabend, jolsa, yanivagman, hengqi.chen This patch set adds more functions to bpf_d_path allowlist. Patch 1 is prep work which updates resolve_btfids to emit warnings on missing symbols instead of aborting kernel build process. Patch 2 expands bpf_d_path allowlist. Changes since v4: [4] - Addressed Andrii's comments. Update warning message. Changes since v3: [3] - Addressed Yonghong's comments. Sort allowlist and add security_bprm_* Changes since v2: [2] - Andrii suggested that we should first address an issue of .BTF_ids before adding more symbols to .BTF_ids. Fixed that. - Yaniv proposed adding security_sb_mount and security_bprm_check. Added them. Changes since v1: [1] - Alexei and Yonghong suggested that bpf_d_path helper could also apply to vfs_* and security_file_* kernel functions. Added them. [1] https://lore.kernel.org/bpf/20210712162424.2034006-1-hengqi.chen@gmail.com/ [2] https://lore.kernel.org/bpf/20210719151753.399227-1-hengqi.chen@gmail.com/ [3] https://lore.kernel.org/bpf/20210725141814.2000828-3-hengqi.chen@gmail.com/ [4] https://lore.kernel.org/bpf/20210725141814.2000828-2-hengqi.chen@gmail.com/ Hengqi Chen (2): tools/resolve_btfids: emit warnings and patch zero id for missing symbols bpf: expose bpf_d_path helper to vfs_* and security_* functions kernel/trace/bpf_trace.c | 60 ++++++++++++++++++++++++++++++--- tools/bpf/resolve_btfids/main.c | 13 +++---- 2 files changed, 63 insertions(+), 10 deletions(-) -- 2.25.1 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH bpf-next v5 1/2] tools/resolve_btfids: emit warnings and patch zero id for missing symbols 2021-07-27 13:25 [PATCH bpf-next v5 0/2] bpf: expand bpf_d_path helper allowlist Hengqi Chen @ 2021-07-27 13:25 ` Hengqi Chen 2021-07-27 13:25 ` [PATCH bpf-next v5 2/2] bpf: expose bpf_d_path helper to vfs_* and security_* functions Hengqi Chen 1 sibling, 0 replies; 7+ messages in thread From: Hengqi Chen @ 2021-07-27 13:25 UTC (permalink / raw) To: bpf Cc: ast, daniel, andrii, yhs, john.fastabend, jolsa, yanivagman, hengqi.chen Kernel functions referenced by .BTF_ids may be changed from global to static and get inlined or get renamed/removed, and thus disappears from BTF. This causes kernel build failure when resolve_btfids do id patch for symbols in .BTF_ids in vmlinux. Update resolve_btfids to emit warning messages and patch zero id for missing symbols instead of aborting kernel build process. Suggested-by: Andrii Nakryiko <andrii@kernel.org> Acked-by: Yonghong Song <yhs@fb.com> Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com> --- tools/bpf/resolve_btfids/main.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c index 3ad9301b0f00..de6365b53c9c 100644 --- a/tools/bpf/resolve_btfids/main.c +++ b/tools/bpf/resolve_btfids/main.c @@ -291,7 +291,7 @@ static int compressed_section_fix(Elf *elf, Elf_Scn *scn, GElf_Shdr *sh) sh->sh_addralign = expected; if (gelf_update_shdr(scn, sh) == 0) { - printf("FAILED cannot update section header: %s\n", + pr_err("FAILED cannot update section header: %s\n", elf_errmsg(-1)); return -1; } @@ -317,6 +317,7 @@ static int elf_collect(struct object *obj) elf = elf_begin(fd, ELF_C_RDWR_MMAP, NULL); if (!elf) { + close(fd); pr_err("FAILED cannot create ELF descriptor: %s\n", elf_errmsg(-1)); return -1; @@ -484,7 +485,7 @@ static int symbols_resolve(struct object *obj) err = libbpf_get_error(btf); if (err) { pr_err("FAILED: load BTF from %s: %s\n", - obj->path, strerror(-err)); + obj->btf ?: obj->path, strerror(-err)); return -1; } @@ -555,8 +556,7 @@ static int id_patch(struct object *obj, struct btf_id *id) int i; if (!id->id) { - pr_err("FAILED unresolved symbol %s\n", id->name); - return -EINVAL; + pr_err("WARN: resolve_btfids: unresolved symbol %s\n", id->name); } for (i = 0; i < id->addr_cnt; i++) { @@ -734,8 +734,9 @@ int main(int argc, const char **argv) err = 0; out: - if (obj.efile.elf) + if (obj.efile.elf) { elf_end(obj.efile.elf); - close(obj.efile.fd); + close(obj.efile.fd); + } return err; } -- 2.25.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH bpf-next v5 2/2] bpf: expose bpf_d_path helper to vfs_* and security_* functions 2021-07-27 13:25 [PATCH bpf-next v5 0/2] bpf: expand bpf_d_path helper allowlist Hengqi Chen 2021-07-27 13:25 ` [PATCH bpf-next v5 1/2] tools/resolve_btfids: emit warnings and patch zero id for missing symbols Hengqi Chen @ 2021-07-27 13:25 ` Hengqi Chen 2021-08-04 22:35 ` Daniel Borkmann 1 sibling, 1 reply; 7+ messages in thread From: Hengqi Chen @ 2021-07-27 13:25 UTC (permalink / raw) To: bpf Cc: ast, daniel, andrii, yhs, john.fastabend, jolsa, yanivagman, hengqi.chen Add vfs_* and security_* to bpf_d_path allowlist, so that we can use bpf_d_path helper to extract full file path from these functions' arguments. This will help tools like BCC's filetop[1]/filelife to get full file path. [1] https://github.com/iovisor/bcc/issues/3527 Acked-by: Yonghong Song <yhs@fb.com> Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com> --- kernel/trace/bpf_trace.c | 60 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index c5e0b6a64091..e7b24abcf3bf 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -849,18 +849,70 @@ BPF_CALL_3(bpf_d_path, struct path *, path, char *, buf, u32, sz) BTF_SET_START(btf_allowlist_d_path) #ifdef CONFIG_SECURITY +BTF_ID(func, security_bprm_check) +BTF_ID(func, security_bprm_committed_creds) +BTF_ID(func, security_bprm_committing_creds) +BTF_ID(func, security_bprm_creds_for_exec) +BTF_ID(func, security_bprm_creds_from_file) +BTF_ID(func, security_file_alloc) +BTF_ID(func, security_file_fcntl) +BTF_ID(func, security_file_free) +BTF_ID(func, security_file_ioctl) +BTF_ID(func, security_file_lock) +BTF_ID(func, security_file_open) BTF_ID(func, security_file_permission) +BTF_ID(func, security_file_receive) +BTF_ID(func, security_file_set_fowner) BTF_ID(func, security_inode_getattr) -BTF_ID(func, security_file_open) +BTF_ID(func, security_sb_mount) #endif #ifdef CONFIG_SECURITY_PATH +BTF_ID(func, security_path_chmod) +BTF_ID(func, security_path_chown) +BTF_ID(func, security_path_chroot) +BTF_ID(func, security_path_link) +BTF_ID(func, security_path_mkdir) +BTF_ID(func, security_path_mknod) +BTF_ID(func, security_path_notify) +BTF_ID(func, security_path_rename) +BTF_ID(func, security_path_rmdir) +BTF_ID(func, security_path_symlink) BTF_ID(func, security_path_truncate) +BTF_ID(func, security_path_unlink) #endif -BTF_ID(func, vfs_truncate) -BTF_ID(func, vfs_fallocate) BTF_ID(func, dentry_open) -BTF_ID(func, vfs_getattr) BTF_ID(func, filp_close) +BTF_ID(func, vfs_cancel_lock) +BTF_ID(func, vfs_clone_file_range) +BTF_ID(func, vfs_copy_file_range) +BTF_ID(func, vfs_dedupe_file_range) +BTF_ID(func, vfs_dedupe_file_range_one) +BTF_ID(func, vfs_fadvise) +BTF_ID(func, vfs_fallocate) +BTF_ID(func, vfs_fchmod) +BTF_ID(func, vfs_fchown) +BTF_ID(func, vfs_fsync) +BTF_ID(func, vfs_fsync_range) +BTF_ID(func, vfs_getattr) +BTF_ID(func, vfs_getattr_nosec) +BTF_ID(func, vfs_iocb_iter_read) +BTF_ID(func, vfs_iocb_iter_write) +BTF_ID(func, vfs_ioctl) +BTF_ID(func, vfs_iter_read) +BTF_ID(func, vfs_iter_write) +BTF_ID(func, vfs_llseek) +BTF_ID(func, vfs_lock_file) +BTF_ID(func, vfs_open) +BTF_ID(func, vfs_read) +BTF_ID(func, vfs_readv) +BTF_ID(func, vfs_setlease) +BTF_ID(func, vfs_setpos) +BTF_ID(func, vfs_statfs) +BTF_ID(func, vfs_test_lock) +BTF_ID(func, vfs_truncate) +BTF_ID(func, vfs_utimes) +BTF_ID(func, vfs_write) +BTF_ID(func, vfs_writev) BTF_SET_END(btf_allowlist_d_path) static bool bpf_d_path_allowed(const struct bpf_prog *prog) -- 2.25.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH bpf-next v5 2/2] bpf: expose bpf_d_path helper to vfs_* and security_* functions 2021-07-27 13:25 ` [PATCH bpf-next v5 2/2] bpf: expose bpf_d_path helper to vfs_* and security_* functions Hengqi Chen @ 2021-08-04 22:35 ` Daniel Borkmann 2021-08-04 22:44 ` Andrii Nakryiko 0 siblings, 1 reply; 7+ messages in thread From: Daniel Borkmann @ 2021-08-04 22:35 UTC (permalink / raw) To: Hengqi Chen, bpf Cc: ast, andrii, yhs, john.fastabend, jolsa, yanivagman, kpsingh On 7/27/21 3:25 PM, Hengqi Chen wrote: > Add vfs_* and security_* to bpf_d_path allowlist, so that we can use > bpf_d_path helper to extract full file path from these functions' arguments. > This will help tools like BCC's filetop[1]/filelife to get full file path. > > [1] https://github.com/iovisor/bcc/issues/3527 > > Acked-by: Yonghong Song <yhs@fb.com> > Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com> > --- > kernel/trace/bpf_trace.c | 60 +++++++++++++++++++++++++++++++++++++--- > 1 file changed, 56 insertions(+), 4 deletions(-) > > diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c > index c5e0b6a64091..e7b24abcf3bf 100644 > --- a/kernel/trace/bpf_trace.c > +++ b/kernel/trace/bpf_trace.c > @@ -849,18 +849,70 @@ BPF_CALL_3(bpf_d_path, struct path *, path, char *, buf, u32, sz) > > BTF_SET_START(btf_allowlist_d_path) > #ifdef CONFIG_SECURITY > +BTF_ID(func, security_bprm_check) > +BTF_ID(func, security_bprm_committed_creds) > +BTF_ID(func, security_bprm_committing_creds) > +BTF_ID(func, security_bprm_creds_for_exec) > +BTF_ID(func, security_bprm_creds_from_file) > +BTF_ID(func, security_file_alloc) Did you actually try these out, e.g. attaching BPF progs invoking bpf_d_path() to all these, then generate some workload like kernel build for testing? I presume not, since something like security_file_alloc() would crash the kernel. Right before it's called in __alloc_file() we fetch a struct file from kmemcache, and only populate f->f_cred there. Most LSMs, for example, only populate their secblob through the callback. If you call bpf_d_path(&file->f_path, ...) with it, you'll crash in d_path() when path->dentry->d_op is checked.. given f->f_path is all zeroed structure at that point. Please do your due diligence and invest each of them manually, maybe the best way is to hack up small selftests for each enabled function that our CI can test run? Bit of a one-time effort, but at least it ensures that those additions are sane & checked. > +BTF_ID(func, security_file_fcntl) > +BTF_ID(func, security_file_free) > +BTF_ID(func, security_file_ioctl) > +BTF_ID(func, security_file_lock) > +BTF_ID(func, security_file_open) > BTF_ID(func, security_file_permission) > +BTF_ID(func, security_file_receive) > +BTF_ID(func, security_file_set_fowner) > BTF_ID(func, security_inode_getattr) > -BTF_ID(func, security_file_open) > +BTF_ID(func, security_sb_mount) > #endif > #ifdef CONFIG_SECURITY_PATH > +BTF_ID(func, security_path_chmod) > +BTF_ID(func, security_path_chown) > +BTF_ID(func, security_path_chroot) > +BTF_ID(func, security_path_link) > +BTF_ID(func, security_path_mkdir) > +BTF_ID(func, security_path_mknod) > +BTF_ID(func, security_path_notify) > +BTF_ID(func, security_path_rename) > +BTF_ID(func, security_path_rmdir) > +BTF_ID(func, security_path_symlink) > BTF_ID(func, security_path_truncate) > +BTF_ID(func, security_path_unlink) > #endif > -BTF_ID(func, vfs_truncate) > -BTF_ID(func, vfs_fallocate) > BTF_ID(func, dentry_open) > -BTF_ID(func, vfs_getattr) > BTF_ID(func, filp_close) > +BTF_ID(func, vfs_cancel_lock) > +BTF_ID(func, vfs_clone_file_range) > +BTF_ID(func, vfs_copy_file_range) > +BTF_ID(func, vfs_dedupe_file_range) > +BTF_ID(func, vfs_dedupe_file_range_one) > +BTF_ID(func, vfs_fadvise) > +BTF_ID(func, vfs_fallocate) > +BTF_ID(func, vfs_fchmod) > +BTF_ID(func, vfs_fchown) > +BTF_ID(func, vfs_fsync) > +BTF_ID(func, vfs_fsync_range) > +BTF_ID(func, vfs_getattr) > +BTF_ID(func, vfs_getattr_nosec) > +BTF_ID(func, vfs_iocb_iter_read) > +BTF_ID(func, vfs_iocb_iter_write) > +BTF_ID(func, vfs_ioctl) > +BTF_ID(func, vfs_iter_read) > +BTF_ID(func, vfs_iter_write) > +BTF_ID(func, vfs_llseek) > +BTF_ID(func, vfs_lock_file) > +BTF_ID(func, vfs_open) > +BTF_ID(func, vfs_read) > +BTF_ID(func, vfs_readv) > +BTF_ID(func, vfs_setlease) > +BTF_ID(func, vfs_setpos) > +BTF_ID(func, vfs_statfs) > +BTF_ID(func, vfs_test_lock) > +BTF_ID(func, vfs_truncate) > +BTF_ID(func, vfs_utimes) > +BTF_ID(func, vfs_write) > +BTF_ID(func, vfs_writev) > BTF_SET_END(btf_allowlist_d_path) > > static bool bpf_d_path_allowed(const struct bpf_prog *prog) > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH bpf-next v5 2/2] bpf: expose bpf_d_path helper to vfs_* and security_* functions 2021-08-04 22:35 ` Daniel Borkmann @ 2021-08-04 22:44 ` Andrii Nakryiko 2021-08-05 2:27 ` Hengqi Chen 0 siblings, 1 reply; 7+ messages in thread From: Andrii Nakryiko @ 2021-08-04 22:44 UTC (permalink / raw) To: Daniel Borkmann Cc: Hengqi Chen, bpf, Alexei Starovoitov, Andrii Nakryiko, Yonghong Song, john fastabend, Jiri Olsa, Yaniv Agman, KP Singh On Wed, Aug 4, 2021 at 3:35 PM Daniel Borkmann <daniel@iogearbox.net> wrote: > > On 7/27/21 3:25 PM, Hengqi Chen wrote: > > Add vfs_* and security_* to bpf_d_path allowlist, so that we can use > > bpf_d_path helper to extract full file path from these functions' arguments. > > This will help tools like BCC's filetop[1]/filelife to get full file path. > > > > [1] https://github.com/iovisor/bcc/issues/3527 > > > > Acked-by: Yonghong Song <yhs@fb.com> > > Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com> > > --- > > kernel/trace/bpf_trace.c | 60 +++++++++++++++++++++++++++++++++++++--- > > 1 file changed, 56 insertions(+), 4 deletions(-) > > > > diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c > > index c5e0b6a64091..e7b24abcf3bf 100644 > > --- a/kernel/trace/bpf_trace.c > > +++ b/kernel/trace/bpf_trace.c > > @@ -849,18 +849,70 @@ BPF_CALL_3(bpf_d_path, struct path *, path, char *, buf, u32, sz) > > > > BTF_SET_START(btf_allowlist_d_path) > > #ifdef CONFIG_SECURITY > > +BTF_ID(func, security_bprm_check) > > +BTF_ID(func, security_bprm_committed_creds) > > +BTF_ID(func, security_bprm_committing_creds) > > +BTF_ID(func, security_bprm_creds_for_exec) > > +BTF_ID(func, security_bprm_creds_from_file) > > +BTF_ID(func, security_file_alloc) > > Did you actually try these out, e.g. attaching BPF progs invoking bpf_d_path() to all > these, then generate some workload like kernel build for testing? > > I presume not, since something like security_file_alloc() would crash the kernel. Right > before it's called in __alloc_file() we fetch a struct file from kmemcache, and only > populate f->f_cred there. Most LSMs, for example, only populate their secblob through the > callback. If you call bpf_d_path(&file->f_path, ...) with it, you'll crash in d_path() > when path->dentry->d_op is checked.. given f->f_path is all zeroed structure at that > point. > > Please do your due diligence and invest each of them manually, maybe the best way is > to hack up small selftests for each enabled function that our CI can test run? Bit of a > one-time effort, but at least it ensures that those additions are sane & checked. I think it's actually a pretty fun exercise and a good selftest to have. We can have a selftest which will attach a simple BPF program just to grab a contents of btf_allowlist_d_path (with typeless ksyms, for instance). Then for each BTF ID in there, as a subtest, attach another BPF object with fentry BPF program doing something with d_path. Hengqi, you'd need to have few variants for each possible position of file or path struct (e.g., file as first arg; as second arg; etc, same for hooks working with path directly), but I don't think that's going to be a lot of them. So as Daniel said, a bit of a work, but we'll have a much better confidence that we are not accidentally opening a big kernel crashing loophole. > > > +BTF_ID(func, security_file_fcntl) > > +BTF_ID(func, security_file_free) > > +BTF_ID(func, security_file_ioctl) > > +BTF_ID(func, security_file_lock) > > +BTF_ID(func, security_file_open) > > BTF_ID(func, security_file_permission) > > +BTF_ID(func, security_file_receive) > > +BTF_ID(func, security_file_set_fowner) > > BTF_ID(func, security_inode_getattr) > > -BTF_ID(func, security_file_open) > > +BTF_ID(func, security_sb_mount) > > #endif > > #ifdef CONFIG_SECURITY_PATH > > +BTF_ID(func, security_path_chmod) > > +BTF_ID(func, security_path_chown) > > +BTF_ID(func, security_path_chroot) > > +BTF_ID(func, security_path_link) > > +BTF_ID(func, security_path_mkdir) > > +BTF_ID(func, security_path_mknod) > > +BTF_ID(func, security_path_notify) > > +BTF_ID(func, security_path_rename) > > +BTF_ID(func, security_path_rmdir) > > +BTF_ID(func, security_path_symlink) > > BTF_ID(func, security_path_truncate) > > +BTF_ID(func, security_path_unlink) > > #endif > > -BTF_ID(func, vfs_truncate) > > -BTF_ID(func, vfs_fallocate) > > BTF_ID(func, dentry_open) > > -BTF_ID(func, vfs_getattr) > > BTF_ID(func, filp_close) > > +BTF_ID(func, vfs_cancel_lock) > > +BTF_ID(func, vfs_clone_file_range) > > +BTF_ID(func, vfs_copy_file_range) > > +BTF_ID(func, vfs_dedupe_file_range) > > +BTF_ID(func, vfs_dedupe_file_range_one) > > +BTF_ID(func, vfs_fadvise) > > +BTF_ID(func, vfs_fallocate) > > +BTF_ID(func, vfs_fchmod) > > +BTF_ID(func, vfs_fchown) > > +BTF_ID(func, vfs_fsync) > > +BTF_ID(func, vfs_fsync_range) > > +BTF_ID(func, vfs_getattr) > > +BTF_ID(func, vfs_getattr_nosec) > > +BTF_ID(func, vfs_iocb_iter_read) > > +BTF_ID(func, vfs_iocb_iter_write) > > +BTF_ID(func, vfs_ioctl) > > +BTF_ID(func, vfs_iter_read) > > +BTF_ID(func, vfs_iter_write) > > +BTF_ID(func, vfs_llseek) > > +BTF_ID(func, vfs_lock_file) > > +BTF_ID(func, vfs_open) > > +BTF_ID(func, vfs_read) > > +BTF_ID(func, vfs_readv) > > +BTF_ID(func, vfs_setlease) > > +BTF_ID(func, vfs_setpos) > > +BTF_ID(func, vfs_statfs) > > +BTF_ID(func, vfs_test_lock) > > +BTF_ID(func, vfs_truncate) > > +BTF_ID(func, vfs_utimes) > > +BTF_ID(func, vfs_write) > > +BTF_ID(func, vfs_writev) > > BTF_SET_END(btf_allowlist_d_path) > > > > static bool bpf_d_path_allowed(const struct bpf_prog *prog) > > > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH bpf-next v5 2/2] bpf: expose bpf_d_path helper to vfs_* and security_* functions 2021-08-04 22:44 ` Andrii Nakryiko @ 2021-08-05 2:27 ` Hengqi Chen 2021-08-05 17:28 ` KP Singh 0 siblings, 1 reply; 7+ messages in thread From: Hengqi Chen @ 2021-08-05 2:27 UTC (permalink / raw) To: Andrii Nakryiko, Daniel Borkmann Cc: bpf, Alexei Starovoitov, Andrii Nakryiko, Yonghong Song, john fastabend, Jiri Olsa, Yaniv Agman, KP Singh On 2021/8/5 6:44 AM, Andrii Nakryiko wrote: > On Wed, Aug 4, 2021 at 3:35 PM Daniel Borkmann <daniel@iogearbox.net> wrote: >> >> On 7/27/21 3:25 PM, Hengqi Chen wrote: >>> Add vfs_* and security_* to bpf_d_path allowlist, so that we can use >>> bpf_d_path helper to extract full file path from these functions' arguments. >>> This will help tools like BCC's filetop[1]/filelife to get full file path. >>> >>> [1] https://github.com/iovisor/bcc/issues/3527 >>> >>> Acked-by: Yonghong Song <yhs@fb.com> >>> Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com> >>> --- >>> kernel/trace/bpf_trace.c | 60 +++++++++++++++++++++++++++++++++++++--- >>> 1 file changed, 56 insertions(+), 4 deletions(-) >>> >>> diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c >>> index c5e0b6a64091..e7b24abcf3bf 100644 >>> --- a/kernel/trace/bpf_trace.c >>> +++ b/kernel/trace/bpf_trace.c >>> @@ -849,18 +849,70 @@ BPF_CALL_3(bpf_d_path, struct path *, path, char *, buf, u32, sz) >>> >>> BTF_SET_START(btf_allowlist_d_path) >>> #ifdef CONFIG_SECURITY >>> +BTF_ID(func, security_bprm_check) >>> +BTF_ID(func, security_bprm_committed_creds) >>> +BTF_ID(func, security_bprm_committing_creds) >>> +BTF_ID(func, security_bprm_creds_for_exec) >>> +BTF_ID(func, security_bprm_creds_from_file) >>> +BTF_ID(func, security_file_alloc) >> >> Did you actually try these out, e.g. attaching BPF progs invoking bpf_d_path() to all >> these, then generate some workload like kernel build for testing? >> >> I presume not, since something like security_file_alloc() would crash the kernel. Right >> before it's called in __alloc_file() we fetch a struct file from kmemcache, and only >> populate f->f_cred there. Most LSMs, for example, only populate their secblob through the >> callback. If you call bpf_d_path(&file->f_path, ...) with it, you'll crash in d_path() >> when path->dentry->d_op is checked.. given f->f_path is all zeroed structure at that >> point. >> >> Please do your due diligence and invest each of them manually, maybe the best way is >> to hack up small selftests for each enabled function that our CI can test run? Bit of a >> one-time effort, but at least it ensures that those additions are sane & checked. > > I think it's actually a pretty fun exercise and a good selftest to > have. We can have a selftest which will attach a simple BPF program > just to grab a contents of btf_allowlist_d_path (with typeless ksyms, > for instance). Then for each BTF ID in there, as a subtest, attach > another BPF object with fentry BPF program doing something with > d_path. > > Hengqi, you'd need to have few variants for each possible position of > file or path struct (e.g., file as first arg; as second arg; etc, same > for hooks working with path directly), but I don't think that's going > to be a lot of them. > > So as Daniel said, a bit of a work, but we'll have a much better > confidence that we are not accidentally opening a big kernel crashing > loophole. > Thanks for the review and suggestions. Will test them locally and add selftest for these changes. >> >>> +BTF_ID(func, security_file_fcntl) >>> +BTF_ID(func, security_file_free) >>> +BTF_ID(func, security_file_ioctl) >>> +BTF_ID(func, security_file_lock) >>> +BTF_ID(func, security_file_open) >>> BTF_ID(func, security_file_permission) >>> +BTF_ID(func, security_file_receive) >>> +BTF_ID(func, security_file_set_fowner) >>> BTF_ID(func, security_inode_getattr) >>> -BTF_ID(func, security_file_open) >>> +BTF_ID(func, security_sb_mount) >>> #endif >>> #ifdef CONFIG_SECURITY_PATH >>> +BTF_ID(func, security_path_chmod) >>> +BTF_ID(func, security_path_chown) >>> +BTF_ID(func, security_path_chroot) >>> +BTF_ID(func, security_path_link) >>> +BTF_ID(func, security_path_mkdir) >>> +BTF_ID(func, security_path_mknod) >>> +BTF_ID(func, security_path_notify) >>> +BTF_ID(func, security_path_rename) >>> +BTF_ID(func, security_path_rmdir) >>> +BTF_ID(func, security_path_symlink) >>> BTF_ID(func, security_path_truncate) >>> +BTF_ID(func, security_path_unlink) >>> #endif >>> -BTF_ID(func, vfs_truncate) >>> -BTF_ID(func, vfs_fallocate) >>> BTF_ID(func, dentry_open) >>> -BTF_ID(func, vfs_getattr) >>> BTF_ID(func, filp_close) >>> +BTF_ID(func, vfs_cancel_lock) >>> +BTF_ID(func, vfs_clone_file_range) >>> +BTF_ID(func, vfs_copy_file_range) >>> +BTF_ID(func, vfs_dedupe_file_range) >>> +BTF_ID(func, vfs_dedupe_file_range_one) >>> +BTF_ID(func, vfs_fadvise) >>> +BTF_ID(func, vfs_fallocate) >>> +BTF_ID(func, vfs_fchmod) >>> +BTF_ID(func, vfs_fchown) >>> +BTF_ID(func, vfs_fsync) >>> +BTF_ID(func, vfs_fsync_range) >>> +BTF_ID(func, vfs_getattr) >>> +BTF_ID(func, vfs_getattr_nosec) >>> +BTF_ID(func, vfs_iocb_iter_read) >>> +BTF_ID(func, vfs_iocb_iter_write) >>> +BTF_ID(func, vfs_ioctl) >>> +BTF_ID(func, vfs_iter_read) >>> +BTF_ID(func, vfs_iter_write) >>> +BTF_ID(func, vfs_llseek) >>> +BTF_ID(func, vfs_lock_file) >>> +BTF_ID(func, vfs_open) >>> +BTF_ID(func, vfs_read) >>> +BTF_ID(func, vfs_readv) >>> +BTF_ID(func, vfs_setlease) >>> +BTF_ID(func, vfs_setpos) >>> +BTF_ID(func, vfs_statfs) >>> +BTF_ID(func, vfs_test_lock) >>> +BTF_ID(func, vfs_truncate) >>> +BTF_ID(func, vfs_utimes) >>> +BTF_ID(func, vfs_write) >>> +BTF_ID(func, vfs_writev) >>> BTF_SET_END(btf_allowlist_d_path) >>> >>> static bool bpf_d_path_allowed(const struct bpf_prog *prog) >>> >> ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH bpf-next v5 2/2] bpf: expose bpf_d_path helper to vfs_* and security_* functions 2021-08-05 2:27 ` Hengqi Chen @ 2021-08-05 17:28 ` KP Singh 0 siblings, 0 replies; 7+ messages in thread From: KP Singh @ 2021-08-05 17:28 UTC (permalink / raw) To: Hengqi Chen Cc: Andrii Nakryiko, Daniel Borkmann, bpf, Alexei Starovoitov, Andrii Nakryiko, Yonghong Song, john fastabend, Jiri Olsa, Yaniv Agman On Thu, Aug 5, 2021 at 4:27 AM Hengqi Chen <hengqi.chen@gmail.com> wrote: > > > > On 2021/8/5 6:44 AM, Andrii Nakryiko wrote: > > On Wed, Aug 4, 2021 at 3:35 PM Daniel Borkmann <daniel@iogearbox.net> wrote: > >> > >> On 7/27/21 3:25 PM, Hengqi Chen wrote: > >>> Add vfs_* and security_* to bpf_d_path allowlist, so that we can use > >>> bpf_d_path helper to extract full file path from these functions' arguments. > >>> This will help tools like BCC's filetop[1]/filelife to get full file path. > >>> > >>> [1] https://github.com/iovisor/bcc/issues/3527 > >>> > >>> Acked-by: Yonghong Song <yhs@fb.com> > >>> Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com> > >>> --- > >>> kernel/trace/bpf_trace.c | 60 +++++++++++++++++++++++++++++++++++++--- > >>> 1 file changed, 56 insertions(+), 4 deletions(-) > >>> > >>> diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c > >>> index c5e0b6a64091..e7b24abcf3bf 100644 > >>> --- a/kernel/trace/bpf_trace.c > >>> +++ b/kernel/trace/bpf_trace.c > >>> @@ -849,18 +849,70 @@ BPF_CALL_3(bpf_d_path, struct path *, path, char *, buf, u32, sz) > >>> > >>> BTF_SET_START(btf_allowlist_d_path) > >>> #ifdef CONFIG_SECURITY > >>> +BTF_ID(func, security_bprm_check) > >>> +BTF_ID(func, security_bprm_committed_creds) > >>> +BTF_ID(func, security_bprm_committing_creds) > >>> +BTF_ID(func, security_bprm_creds_for_exec) > >>> +BTF_ID(func, security_bprm_creds_from_file) > >>> +BTF_ID(func, security_file_alloc) You can also look at the set of LSM hooks that are allow listed for bpf_d_path: https://elixir.bootlin.com/linux/latest/source/kernel/bpf/bpf_lsm.c you could refactor this set so that it also adds the corresponding security_* functions for tracing programs. > >> > >> Did you actually try these out, e.g. attaching BPF progs invoking bpf_d_path() to all > >> these, then generate some workload like kernel build for testing? > >> > >> I presume not, since something like security_file_alloc() would crash the kernel. Right > >> before it's called in __alloc_file() we fetch a struct file from kmemcache, and only > >> populate f->f_cred there. Most LSMs, for example, only populate their secblob through the > >> callback. If you call bpf_d_path(&file->f_path, ...) with it, you'll crash in d_path() > >> when path->dentry->d_op is checked.. given f->f_path is all zeroed structure at that > >> point. > >> > >> Please do your due diligence and invest each of them manually, maybe the best way is > >> to hack up small selftests for each enabled function that our CI can test run? Bit of a > >> one-time effort, but at least it ensures that those additions are sane & checked. > > > > I think it's actually a pretty fun exercise and a good selftest to > > have. We can have a selftest which will attach a simple BPF program > > just to grab a contents of btf_allowlist_d_path (with typeless ksyms, > > for instance). Then for each BTF ID in there, as a subtest, attach > > another BPF object with fentry BPF program doing something with > > d_path. +1 Good idea! > > > > Hengqi, you'd need to have few variants for each possible position of > > file or path struct (e.g., file as first arg; as second arg; etc, same > > for hooks working with path directly), but I don't think that's going > > to be a lot of them. > > > > So as Daniel said, a bit of a work, but we'll have a much better > > confidence that we are not accidentally opening a big kernel crashing > > loophole. > > > > Thanks for the review and suggestions. > [...] > >> ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2021-08-05 17:28 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-07-27 13:25 [PATCH bpf-next v5 0/2] bpf: expand bpf_d_path helper allowlist Hengqi Chen 2021-07-27 13:25 ` [PATCH bpf-next v5 1/2] tools/resolve_btfids: emit warnings and patch zero id for missing symbols Hengqi Chen 2021-07-27 13:25 ` [PATCH bpf-next v5 2/2] bpf: expose bpf_d_path helper to vfs_* and security_* functions Hengqi Chen 2021-08-04 22:35 ` Daniel Borkmann 2021-08-04 22:44 ` Andrii Nakryiko 2021-08-05 2:27 ` Hengqi Chen 2021-08-05 17:28 ` KP Singh
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.