Skip to content

Commit af4ac7e

Browse files
Guillaume GonnetKernel Patches Daemon
authored andcommitted
bpf: Fix tcx/netkit detach permissions when prog fd isn't given
This commit fixes a security issue where BPF_PROG_DETACH on tcx or netkit devices could be executed by any user when no program fd was provided, bypassing permission checks. The fix adds a capability check for CAP_NET_ADMIN or CAP_SYS_ADMIN in this case. Fixes: e420bed ("bpf: Add fd-based tcx multi-prog infra with link support") Signed-off-by: Guillaume Gonnet <ggonnet.linux@gmail.com>
1 parent 623eff3 commit af4ac7e

File tree

3 files changed

+17
-5
lines changed

3 files changed

+17
-5
lines changed

include/linux/bpf.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3243,6 +3243,11 @@ static inline void bpf_prog_report_arena_violation(bool write, unsigned long add
32433243
}
32443244
#endif /* CONFIG_BPF_SYSCALL */
32453245

3246+
static inline bool bpf_net_capable(void)
3247+
{
3248+
return capable(CAP_NET_ADMIN) || capable(CAP_SYS_ADMIN);
3249+
}
3250+
32463251
static __always_inline int
32473252
bpf_probe_read_kernel_common(void *dst, u32 size, const void *unsafe_ptr)
32483253
{

include/linux/bpf_mprog.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,4 +340,14 @@ static inline bool bpf_mprog_supported(enum bpf_prog_type type)
340340
return false;
341341
}
342342
}
343+
344+
static inline bool bpf_mprog_detach_empty(enum bpf_prog_type type)
345+
{
346+
switch (type) {
347+
case BPF_PROG_TYPE_SCHED_CLS:
348+
return bpf_net_capable();
349+
default:
350+
return false;
351+
}
352+
}
343353
#endif /* __BPF_MPROG_H */

kernel/bpf/syscall.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,11 +1366,6 @@ static int map_check_btf(struct bpf_map *map, struct bpf_token *token,
13661366
return ret;
13671367
}
13681368

1369-
static bool bpf_net_capable(void)
1370-
{
1371-
return capable(CAP_NET_ADMIN) || capable(CAP_SYS_ADMIN);
1372-
}
1373-
13741369
#define BPF_MAP_CREATE_LAST_FIELD excl_prog_hash_size
13751370
/* called via syscall */
13761371
static int map_create(union bpf_attr *attr, bpfptr_t uattr)
@@ -4565,6 +4560,8 @@ static int bpf_prog_detach(const union bpf_attr *attr)
45654560
prog = bpf_prog_get_type(attr->attach_bpf_fd, ptype);
45664561
if (IS_ERR(prog))
45674562
return PTR_ERR(prog);
4563+
} else if (!bpf_mprog_detach_empty(ptype)) {
4564+
return -EPERM;
45684565
}
45694566
} else if (is_cgroup_prog_type(ptype, 0, false)) {
45704567
if (attr->attach_flags || attr->relative_fd)

0 commit comments

Comments
 (0)