On Tue, Mar 4, 2025 at 1:15 PM Mykyta Yatsenko <mykyta.yatsenko5@xxxxxxxxx> wrote: > > From: Mykyta Yatsenko <yatsenko@xxxxxxxx> > > Currently BPF_BTF_GET_FD_BY_ID requires CAP_SYS_ADMIN, which does not > allow running it from user namespace. This creates a problem when > freplace program running from user namespace needs to query target > program BTF. > This patch relaxes capable check from CAP_SYS_ADMIN to CAP_BPF and adds > support for BPF token that can be passed in attributes to syscall. > > Signed-off-by: Mykyta Yatsenko <yatsenko@xxxxxxxx> > --- > include/uapi/linux/bpf.h | 1 + > kernel/bpf/syscall.c | 12 ++++++++---- > 2 files changed, 9 insertions(+), 4 deletions(-) > > diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h > index bb37897c0393..73c23daacabf 100644 > --- a/include/uapi/linux/bpf.h > +++ b/include/uapi/linux/bpf.h > @@ -1652,6 +1652,7 @@ union bpf_attr { > }; > __u32 next_id; > __u32 open_flags; > + __s32 token_fd; > }; > > struct { /* anonymous struct used by BPF_OBJ_GET_INFO_BY_FD */ > diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c > index 57a438706215..487054cb4704 100644 > --- a/kernel/bpf/syscall.c > +++ b/kernel/bpf/syscall.c > @@ -4750,6 +4750,9 @@ static int bpf_prog_get_info_by_fd(struct file *file, > > info.verified_insns = prog->aux->verified_insns; > > + if (prog->aux->btf) > + info.btf_id = btf_obj_id(prog->aux->btf); > + please split this change into its own patch > if (!bpf_capable()) { > info.jited_prog_len = 0; > info.xlated_prog_len = 0; > @@ -4895,8 +4898,6 @@ static int bpf_prog_get_info_by_fd(struct file *file, > } > } > > - if (prog->aux->btf) > - info.btf_id = btf_obj_id(prog->aux->btf); > info.attach_btf_id = prog->aux->attach_btf_id; > if (attach_btf) > info.attach_btf_obj_id = btf_obj_id(attach_btf); > @@ -5137,14 +5138,17 @@ static int bpf_btf_load(const union bpf_attr *attr, bpfptr_t uattr, __u32 uattr_ > return btf_new_fd(attr, uattr, uattr_size); > } > > -#define BPF_BTF_GET_FD_BY_ID_LAST_FIELD btf_id > +#define BPF_BTF_GET_FD_BY_ID_LAST_FIELD token_fd > > static int bpf_btf_get_fd_by_id(const union bpf_attr *attr) > { > + struct bpf_token *token; > + > if (CHECK_ATTR(BPF_BTF_GET_FD_BY_ID)) > return -EINVAL; > > - if (!capable(CAP_SYS_ADMIN)) > + token = attr->token_fd ? bpf_token_get_from_fd(attr->token_fd) : NULL; see how we use BPF_F_TOKEN_FD flag in other places, we should do the same here pw-bot: cr > + if (!bpf_token_capable(token, CAP_BPF)) we probably should keep it CAP_SYS_ADMIN, just do s/capable/bpf_token_capable/ change > return -EPERM; > > return btf_get_fd_by_id(attr->btf_id); > -- > 2.48.1 >