From: Pu Lehui In bpf_netns_link_update_prog, the checks for old_prog and prog type are currently performed locklessly before acquiring netns_bpf_mutex. This creates a race condition that can lead to a UAF issue. If two threads concurrently execute BPF_LINK_UPDATE on the same netns link, the following execution path can trigger a UAF: CPU0 CPU1 bpf_netns_link_update_prog if (old_prog && old_prog != link->prog) return -EPERM; bpf_netns_link_update_prog if (old_prog && old_prog != link->prog) ... old_prog = xchg(&link->prog, new_prog); bpf_prog_put(old_prog); if (new_prog->type != link->prog->type) <-- trigger UAF Fix this by moving the old_prog and prog->type checks inside the netns_bpf_mutex critical section. Fixes: 7f045a49fee0 ("bpf: Add link-based BPF program attachment to network namespace") Reported-by: Sashiko Reviewed-by: Amery Hung Signed-off-by: Pu Lehui --- kernel/bpf/net_namespace.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/kernel/bpf/net_namespace.c b/kernel/bpf/net_namespace.c index 25f30f9edaef..9fc62db1441c 100644 --- a/kernel/bpf/net_namespace.c +++ b/kernel/bpf/net_namespace.c @@ -171,13 +171,17 @@ static int bpf_netns_link_update_prog(struct bpf_link *link, struct net *net; int idx, ret; - if (old_prog && old_prog != link->prog) - return -EPERM; - if (new_prog->type != link->prog->type) - return -EINVAL; - mutex_lock(&netns_bpf_mutex); + if (old_prog && old_prog != link->prog) { + ret = -EPERM; + goto out_unlock; + } + if (new_prog->type != link->prog->type) { + ret = -EINVAL; + goto out_unlock; + } + net = net_link->net; if (!net || !check_net(net)) { /* Link auto-detached or netns dying */ -- 2.34.1