summaryrefslogtreecommitdiff
path: root/kernel/bpf/syscall.c
diff options
context:
space:
mode:
authorAndrii Nakryiko <andrii@kernel.org>2023-12-19 07:37:35 -0800
committerAndrii Nakryiko <andrii@kernel.org>2023-12-19 08:23:03 -0800
commitd17aff807f845cf93926c28705216639c7279110 (patch)
tree2c7baaedac92384e2d4d083ddebfba920b3390ae /kernel/bpf/syscall.c
parent2130c519a401e576647040043cb46d6fdc361dcc (diff)
Revert BPF token-related functionality
This patch includes the following revert (one conflicting BPF FS patch and three token patch sets, represented by merge commits): - revert 0f5d5454c723 "Merge branch 'bpf-fs-mount-options-parsing-follow-ups'"; - revert 750e785796bb "bpf: Support uid and gid when mounting bpffs"; - revert 733763285acf "Merge branch 'bpf-token-support-in-libbpf-s-bpf-object'"; - revert c35919dcce28 "Merge branch 'bpf-token-and-bpf-fs-based-delegation'". Link: https://lore.kernel.org/bpf/CAHk-=wg7JuFYwGy=GOMbRCtOL+jwSQsdUaBsRWkDVYbxipbM5A@mail.gmail.com Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Diffstat (limited to 'kernel/bpf/syscall.c')
-rw-r--r--kernel/bpf/syscall.c215
1 files changed, 56 insertions, 159 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 8faa1a20edf8..1bf9805ee185 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -1011,8 +1011,8 @@ int map_check_no_btf(const struct bpf_map *map,
return -ENOTSUPP;
}
-static int map_check_btf(struct bpf_map *map, struct bpf_token *token,
- const struct btf *btf, u32 btf_key_id, u32 btf_value_id)
+static int map_check_btf(struct bpf_map *map, const struct btf *btf,
+ u32 btf_key_id, u32 btf_value_id)
{
const struct btf_type *key_type, *value_type;
u32 key_size, value_size;
@@ -1040,7 +1040,7 @@ static int map_check_btf(struct bpf_map *map, struct bpf_token *token,
if (!IS_ERR_OR_NULL(map->record)) {
int i;
- if (!bpf_token_capable(token, CAP_BPF)) {
+ if (!bpf_capable()) {
ret = -EPERM;
goto free_map_tab;
}
@@ -1123,17 +1123,11 @@ free_map_tab:
return ret;
}
-static bool bpf_net_capable(void)
-{
- return capable(CAP_NET_ADMIN) || capable(CAP_SYS_ADMIN);
-}
-
-#define BPF_MAP_CREATE_LAST_FIELD map_token_fd
+#define BPF_MAP_CREATE_LAST_FIELD map_extra
/* called via syscall */
static int map_create(union bpf_attr *attr)
{
const struct bpf_map_ops *ops;
- struct bpf_token *token = NULL;
int numa_node = bpf_map_attr_numa_node(attr);
u32 map_type = attr->map_type;
struct bpf_map *map;
@@ -1184,32 +1178,14 @@ static int map_create(union bpf_attr *attr)
if (!ops->map_mem_usage)
return -EINVAL;
- if (attr->map_token_fd) {
- token = bpf_token_get_from_fd(attr->map_token_fd);
- if (IS_ERR(token))
- return PTR_ERR(token);
-
- /* if current token doesn't grant map creation permissions,
- * then we can't use this token, so ignore it and rely on
- * system-wide capabilities checks
- */
- if (!bpf_token_allow_cmd(token, BPF_MAP_CREATE) ||
- !bpf_token_allow_map_type(token, attr->map_type)) {
- bpf_token_put(token);
- token = NULL;
- }
- }
-
- err = -EPERM;
-
/* Intent here is for unprivileged_bpf_disabled to block BPF map
* creation for unprivileged users; other actions depend
* on fd availability and access to bpffs, so are dependent on
* object creation success. Even with unprivileged BPF disabled,
* capability checks are still carried out.
*/
- if (sysctl_unprivileged_bpf_disabled && !bpf_token_capable(token, CAP_BPF))
- goto put_token;
+ if (sysctl_unprivileged_bpf_disabled && !bpf_capable())
+ return -EPERM;
/* check privileged map type permissions */
switch (map_type) {
@@ -1242,27 +1218,25 @@ static int map_create(union bpf_attr *attr)
case BPF_MAP_TYPE_LRU_PERCPU_HASH:
case BPF_MAP_TYPE_STRUCT_OPS:
case BPF_MAP_TYPE_CPUMAP:
- if (!bpf_token_capable(token, CAP_BPF))
- goto put_token;
+ if (!bpf_capable())
+ return -EPERM;
break;
case BPF_MAP_TYPE_SOCKMAP:
case BPF_MAP_TYPE_SOCKHASH:
case BPF_MAP_TYPE_DEVMAP:
case BPF_MAP_TYPE_DEVMAP_HASH:
case BPF_MAP_TYPE_XSKMAP:
- if (!bpf_token_capable(token, CAP_NET_ADMIN))
- goto put_token;
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
break;
default:
WARN(1, "unsupported map type %d", map_type);
- goto put_token;
+ return -EPERM;
}
map = ops->map_alloc(attr);
- if (IS_ERR(map)) {
- err = PTR_ERR(map);
- goto put_token;
- }
+ if (IS_ERR(map))
+ return PTR_ERR(map);
map->ops = ops;
map->map_type = map_type;
@@ -1299,7 +1273,7 @@ static int map_create(union bpf_attr *attr)
map->btf = btf;
if (attr->btf_value_type_id) {
- err = map_check_btf(map, token, btf, attr->btf_key_type_id,
+ err = map_check_btf(map, btf, attr->btf_key_type_id,
attr->btf_value_type_id);
if (err)
goto free_map;
@@ -1311,16 +1285,15 @@ static int map_create(union bpf_attr *attr)
attr->btf_vmlinux_value_type_id;
}
- err = security_bpf_map_create(map, attr, token);
+ err = security_bpf_map_alloc(map);
if (err)
- goto free_map_sec;
+ goto free_map;
err = bpf_map_alloc_id(map);
if (err)
goto free_map_sec;
bpf_map_save_memcg(map);
- bpf_token_put(token);
err = bpf_map_new_fd(map, f_flags);
if (err < 0) {
@@ -1341,8 +1314,6 @@ free_map_sec:
free_map:
btf_put(map->btf);
map->ops->map_free(map);
-put_token:
- bpf_token_put(token);
return err;
}
@@ -2173,7 +2144,7 @@ static void __bpf_prog_put_rcu(struct rcu_head *rcu)
kvfree(aux->func_info);
kfree(aux->func_info_aux);
free_uid(aux->user);
- security_bpf_prog_free(aux->prog);
+ security_bpf_prog_free(aux);
bpf_prog_free(aux->prog);
}
@@ -2619,15 +2590,13 @@ static bool is_perfmon_prog_type(enum bpf_prog_type prog_type)
}
/* last field in 'union bpf_attr' used by this command */
-#define BPF_PROG_LOAD_LAST_FIELD prog_token_fd
+#define BPF_PROG_LOAD_LAST_FIELD log_true_size
static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
{
enum bpf_prog_type type = attr->prog_type;
struct bpf_prog *prog, *dst_prog = NULL;
struct btf *attach_btf = NULL;
- struct bpf_token *token = NULL;
- bool bpf_cap;
int err;
char license[128];
@@ -2644,31 +2613,10 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
BPF_F_TEST_REG_INVARIANTS))
return -EINVAL;
- bpf_prog_load_fixup_attach_type(attr);
-
- if (attr->prog_token_fd) {
- token = bpf_token_get_from_fd(attr->prog_token_fd);
- if (IS_ERR(token))
- return PTR_ERR(token);
- /* if current token doesn't grant prog loading permissions,
- * then we can't use this token, so ignore it and rely on
- * system-wide capabilities checks
- */
- if (!bpf_token_allow_cmd(token, BPF_PROG_LOAD) ||
- !bpf_token_allow_prog_type(token, attr->prog_type,
- attr->expected_attach_type)) {
- bpf_token_put(token);
- token = NULL;
- }
- }
-
- bpf_cap = bpf_token_capable(token, CAP_BPF);
- err = -EPERM;
-
if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) &&
(attr->prog_flags & BPF_F_ANY_ALIGNMENT) &&
- !bpf_cap)
- goto put_token;
+ !bpf_capable())
+ return -EPERM;
/* Intent here is for unprivileged_bpf_disabled to block BPF program
* creation for unprivileged users; other actions depend
@@ -2677,23 +2625,21 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
* capability checks are still carried out for these
* and other operations.
*/
- if (sysctl_unprivileged_bpf_disabled && !bpf_cap)
- goto put_token;
+ if (sysctl_unprivileged_bpf_disabled && !bpf_capable())
+ return -EPERM;
if (attr->insn_cnt == 0 ||
- attr->insn_cnt > (bpf_cap ? BPF_COMPLEXITY_LIMIT_INSNS : BPF_MAXINSNS)) {
- err = -E2BIG;
- goto put_token;
- }
+ attr->insn_cnt > (bpf_capable() ? BPF_COMPLEXITY_LIMIT_INSNS : BPF_MAXINSNS))
+ return -E2BIG;
if (type != BPF_PROG_TYPE_SOCKET_FILTER &&
type != BPF_PROG_TYPE_CGROUP_SKB &&
- !bpf_cap)
- goto put_token;
+ !bpf_capable())
+ return -EPERM;
- if (is_net_admin_prog_type(type) && !bpf_token_capable(token, CAP_NET_ADMIN))
- goto put_token;
- if (is_perfmon_prog_type(type) && !bpf_token_capable(token, CAP_PERFMON))
- goto put_token;
+ if (is_net_admin_prog_type(type) && !capable(CAP_NET_ADMIN) && !capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ if (is_perfmon_prog_type(type) && !perfmon_capable())
+ return -EPERM;
/* attach_prog_fd/attach_btf_obj_fd can specify fd of either bpf_prog
* or btf, we need to check which one it is
@@ -2703,33 +2649,27 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
if (IS_ERR(dst_prog)) {
dst_prog = NULL;
attach_btf = btf_get_by_fd(attr->attach_btf_obj_fd);
- if (IS_ERR(attach_btf)) {
- err = -EINVAL;
- goto put_token;
- }
+ if (IS_ERR(attach_btf))
+ return -EINVAL;
if (!btf_is_kernel(attach_btf)) {
/* attaching through specifying bpf_prog's BTF
* objects directly might be supported eventually
*/
btf_put(attach_btf);
- err = -ENOTSUPP;
- goto put_token;
+ return -ENOTSUPP;
}
}
} else if (attr->attach_btf_id) {
/* fall back to vmlinux BTF, if BTF type ID is specified */
attach_btf = bpf_get_btf_vmlinux();
- if (IS_ERR(attach_btf)) {
- err = PTR_ERR(attach_btf);
- goto put_token;
- }
- if (!attach_btf) {
- err = -EINVAL;
- goto put_token;
- }
+ if (IS_ERR(attach_btf))
+ return PTR_ERR(attach_btf);
+ if (!attach_btf)
+ return -EINVAL;
btf_get(attach_btf);
}
+ bpf_prog_load_fixup_attach_type(attr);
if (bpf_prog_load_check_attach(type, attr->expected_attach_type,
attach_btf, attr->attach_btf_id,
dst_prog)) {
@@ -2737,8 +2677,7 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
bpf_prog_put(dst_prog);
if (attach_btf)
btf_put(attach_btf);
- err = -EINVAL;
- goto put_token;
+ return -EINVAL;
}
/* plain bpf_prog allocation */
@@ -2748,8 +2687,7 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
bpf_prog_put(dst_prog);
if (attach_btf)
btf_put(attach_btf);
- err = -EINVAL;
- goto put_token;
+ return -ENOMEM;
}
prog->expected_attach_type = attr->expected_attach_type;
@@ -2760,9 +2698,9 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
prog->aux->sleepable = attr->prog_flags & BPF_F_SLEEPABLE;
prog->aux->xdp_has_frags = attr->prog_flags & BPF_F_XDP_HAS_FRAGS;
- /* move token into prog->aux, reuse taken refcnt */
- prog->aux->token = token;
- token = NULL;
+ err = security_bpf_prog_alloc(prog->aux);
+ if (err)
+ goto free_prog;
prog->aux->user = get_current_user();
prog->len = attr->insn_cnt;
@@ -2771,12 +2709,12 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
if (copy_from_bpfptr(prog->insns,
make_bpfptr(attr->insns, uattr.is_kernel),
bpf_prog_insn_size(prog)) != 0)
- goto free_prog;
+ goto free_prog_sec;
/* copy eBPF program license from user space */
if (strncpy_from_bpfptr(license,
make_bpfptr(attr->license, uattr.is_kernel),
sizeof(license) - 1) < 0)
- goto free_prog;
+ goto free_prog_sec;
license[sizeof(license) - 1] = 0;
/* eBPF programs must be GPL compatible to use GPL-ed functions */
@@ -2790,29 +2728,25 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
if (bpf_prog_is_dev_bound(prog->aux)) {
err = bpf_prog_dev_bound_init(prog, attr);
if (err)
- goto free_prog;
+ goto free_prog_sec;
}
if (type == BPF_PROG_TYPE_EXT && dst_prog &&
bpf_prog_is_dev_bound(dst_prog->aux)) {
err = bpf_prog_dev_bound_inherit(prog, dst_prog);
if (err)
- goto free_prog;
+ goto free_prog_sec;
}
/* find program type: socket_filter vs tracing_filter */
err = find_prog_type(type, prog);
if (err < 0)
- goto free_prog;
+ goto free_prog_sec;
prog->aux->load_time = ktime_get_boottime_ns();
err = bpf_obj_name_cpy(prog->aux->name, attr->prog_name,
sizeof(attr->prog_name));
if (err < 0)
- goto free_prog;
-
- err = security_bpf_prog_load(prog, attr, token);
- if (err)
goto free_prog_sec;
/* run eBPF verifier */
@@ -2858,16 +2792,13 @@ free_used_maps:
*/
__bpf_prog_put_noref(prog, prog->aux->real_func_cnt);
return err;
-
free_prog_sec:
- security_bpf_prog_free(prog);
-free_prog:
free_uid(prog->aux->user);
+ security_bpf_prog_free(prog->aux);
+free_prog:
if (prog->aux->attach_btf)
btf_put(prog->aux->attach_btf);
bpf_prog_free(prog);
-put_token:
- bpf_token_put(token);
return err;
}
@@ -3857,7 +3788,7 @@ static int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog,
case BPF_PROG_TYPE_SK_LOOKUP:
return attach_type == prog->expected_attach_type ? 0 : -EINVAL;
case BPF_PROG_TYPE_CGROUP_SKB:
- if (!bpf_token_capable(prog->aux->token, CAP_NET_ADMIN))
+ if (!capable(CAP_NET_ADMIN))
/* cg-skb progs can be loaded by unpriv user.
* check permissions at attach time.
*/
@@ -4060,7 +3991,7 @@ static int bpf_prog_detach(const union bpf_attr *attr)
static int bpf_prog_query(const union bpf_attr *attr,
union bpf_attr __user *uattr)
{
- if (!bpf_net_capable())
+ if (!capable(CAP_NET_ADMIN))
return -EPERM;
if (CHECK_ATTR(BPF_PROG_QUERY))
return -EINVAL;
@@ -4828,31 +4759,15 @@ static int bpf_obj_get_info_by_fd(const union bpf_attr *attr,
return err;
}
-#define BPF_BTF_LOAD_LAST_FIELD btf_token_fd
+#define BPF_BTF_LOAD_LAST_FIELD btf_log_true_size
static int bpf_btf_load(const union bpf_attr *attr, bpfptr_t uattr, __u32 uattr_size)
{
- struct bpf_token *token = NULL;
-
if (CHECK_ATTR(BPF_BTF_LOAD))
return -EINVAL;
- if (attr->btf_token_fd) {
- token = bpf_token_get_from_fd(attr->btf_token_fd);
- if (IS_ERR(token))
- return PTR_ERR(token);
- if (!bpf_token_allow_cmd(token, BPF_BTF_LOAD)) {
- bpf_token_put(token);
- token = NULL;
- }
- }
-
- if (!bpf_token_capable(token, CAP_BPF)) {
- bpf_token_put(token);
+ if (!bpf_capable())
return -EPERM;
- }
-
- bpf_token_put(token);
return btf_new_fd(attr, uattr, uattr_size);
}
@@ -5470,20 +5385,6 @@ out_prog_put:
return ret;
}
-#define BPF_TOKEN_CREATE_LAST_FIELD token_create.bpffs_fd
-
-static int token_create(union bpf_attr *attr)
-{
- if (CHECK_ATTR(BPF_TOKEN_CREATE))
- return -EINVAL;
-
- /* no flags are supported yet */
- if (attr->token_create.flags)
- return -EINVAL;
-
- return bpf_token_create(attr);
-}
-
static int __sys_bpf(int cmd, bpfptr_t uattr, unsigned int size)
{
union bpf_attr attr;
@@ -5617,9 +5518,6 @@ static int __sys_bpf(int cmd, bpfptr_t uattr, unsigned int size)
case BPF_PROG_BIND_MAP:
err = bpf_prog_bind_map(&attr);
break;
- case BPF_TOKEN_CREATE:
- err = token_create(&attr);
- break;
default:
err = -EINVAL;
break;
@@ -5726,7 +5624,7 @@ static const struct bpf_func_proto bpf_sys_bpf_proto = {
const struct bpf_func_proto * __weak
tracing_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{
- return bpf_base_func_proto(func_id, prog);
+ return bpf_base_func_proto(func_id);
}
BPF_CALL_1(bpf_sys_close, u32, fd)
@@ -5776,8 +5674,7 @@ syscall_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{
switch (func_id) {
case BPF_FUNC_sys_bpf:
- return !bpf_token_capable(prog->aux->token, CAP_PERFMON)
- ? NULL : &bpf_sys_bpf_proto;
+ return !perfmon_capable() ? NULL : &bpf_sys_bpf_proto;
case BPF_FUNC_btf_find_by_name_kind:
return &bpf_btf_find_by_name_kind_proto;
case BPF_FUNC_sys_close: