Commit ae23bc81 authored by Guillaume Gonnet's avatar Guillaume Gonnet Committed by Alexei Starovoitov
Browse files

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: e420bed0 ("bpf: Add fd-based tcx multi-prog infra with link support")
Signed-off-by: default avatarGuillaume Gonnet <ggonnet.linux@gmail.com>
Link: https://lore.kernel.org/r/20260127160200.10395-1-ggonnet.linux@gmail.com


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 35538dba
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -3362,6 +3362,11 @@ static inline void bpf_prog_report_arena_violation(bool write, unsigned long add
}
#endif /* CONFIG_BPF_SYSCALL */

static inline bool bpf_net_capable(void)
{
	return capable(CAP_NET_ADMIN) || capable(CAP_SYS_ADMIN);
}

static __always_inline int
bpf_probe_read_kernel_common(void *dst, u32 size, const void *unsafe_ptr)
{
+10 −0
Original line number Diff line number Diff line
@@ -340,4 +340,14 @@ static inline bool bpf_mprog_supported(enum bpf_prog_type type)
		return false;
	}
}

static inline bool bpf_mprog_detach_empty(enum bpf_prog_type type)
{
	switch (type) {
	case BPF_PROG_TYPE_SCHED_CLS:
		return bpf_net_capable();
	default:
		return false;
	}
}
#endif /* __BPF_MPROG_H */
+2 −5
Original line number Diff line number Diff line
@@ -1363,11 +1363,6 @@ static int map_check_btf(struct bpf_map *map, struct bpf_token *token,
	return ret;
}

static bool bpf_net_capable(void)
{
	return capable(CAP_NET_ADMIN) || capable(CAP_SYS_ADMIN);
}

#define BPF_MAP_CREATE_LAST_FIELD excl_prog_hash_size
/* called via syscall */
static int map_create(union bpf_attr *attr, bpfptr_t uattr)
@@ -4579,6 +4574,8 @@ static int bpf_prog_detach(const union bpf_attr *attr)
			prog = bpf_prog_get_type(attr->attach_bpf_fd, ptype);
			if (IS_ERR(prog))
				return PTR_ERR(prog);
		} else if (!bpf_mprog_detach_empty(ptype)) {
			return -EPERM;
		}
	} else if (is_cgroup_prog_type(ptype, 0, false)) {
		if (attr->attach_flags || attr->relative_fd)