Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bpf: BPF token support for BPF_BTF_GET_FD_BY_ID

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@meta.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20250317174039.161275-2-mykyta.yatsenko5@gmail.com

authored by

Mykyta Yatsenko and committed by
Andrii Nakryiko
0de445d1 812f7702

+23 -2
+1
include/uapi/linux/bpf.h
··· 1652 1652 }; 1653 1653 __u32 next_id; 1654 1654 __u32 open_flags; 1655 + __s32 fd_by_id_token_fd; 1655 1656 }; 1656 1657 1657 1658 struct { /* anonymous struct used by BPF_OBJ_GET_INFO_BY_FD */
+21 -2
kernel/bpf/syscall.c
··· 5120 5120 return btf_new_fd(attr, uattr, uattr_size); 5121 5121 } 5122 5122 5123 - #define BPF_BTF_GET_FD_BY_ID_LAST_FIELD btf_id 5123 + #define BPF_BTF_GET_FD_BY_ID_LAST_FIELD fd_by_id_token_fd 5124 5124 5125 5125 static int bpf_btf_get_fd_by_id(const union bpf_attr *attr) 5126 5126 { 5127 + struct bpf_token *token = NULL; 5128 + 5127 5129 if (CHECK_ATTR(BPF_BTF_GET_FD_BY_ID)) 5128 5130 return -EINVAL; 5129 5131 5130 - if (!capable(CAP_SYS_ADMIN)) 5132 + if (attr->open_flags & ~BPF_F_TOKEN_FD) 5133 + return -EINVAL; 5134 + 5135 + if (attr->open_flags & BPF_F_TOKEN_FD) { 5136 + token = bpf_token_get_from_fd(attr->fd_by_id_token_fd); 5137 + if (IS_ERR(token)) 5138 + return PTR_ERR(token); 5139 + if (!bpf_token_allow_cmd(token, BPF_BTF_GET_FD_BY_ID)) { 5140 + bpf_token_put(token); 5141 + token = NULL; 5142 + } 5143 + } 5144 + 5145 + if (!bpf_token_capable(token, CAP_SYS_ADMIN)) { 5146 + bpf_token_put(token); 5131 5147 return -EPERM; 5148 + } 5149 + 5150 + bpf_token_put(token); 5132 5151 5133 5152 return btf_get_fd_by_id(attr->btf_id); 5134 5153 }
+1
tools/include/uapi/linux/bpf.h
··· 1652 1652 }; 1653 1653 __u32 next_id; 1654 1654 __u32 open_flags; 1655 + __s32 fd_by_id_token_fd; 1655 1656 }; 1656 1657 1657 1658 struct { /* anonymous struct used by BPF_OBJ_GET_INFO_BY_FD */