From af929bc938e0d0ecd839e6fed9a2ce5eb5185e5c Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Sat, 17 Oct 2026 16:37:23 +0000 Subject: [PATCH] bpf: Don't bind a program to a netdev that goes away bpf_prog_dev_bound_init() looks the device up, takes bpf_devs_lock and registers the device for the program. The reference it holds does not keep the device registered. If bpf_dev_bound_netdev_unregister() has run by the time the lock is taken, nobody takes the program off the device any more: the bpf_offload_netdev and offload->netdev point to a net_device that is freed as soon as the reference is dropped. bpf_dev_bound_resolve_kfunc() dereferences it while the program is verified, and a new device at the same address finds the old entry. unregister_netdevice_many_notify() leaves NETREG_REGISTERED before it calls bpf_dev_bound_netdev_unregister(), which takes bpf_devs_lock. Look at reg_state under that lock, and treat a device that goes like one that is not there. Fixes: 2b3486bc2d23 ("bpf: Introduce device-bound XDP programs") Signed-off-by: Josef Bacik Signed-off-by: Alexei Starovoitov Link: https://patch.msgid.link/20261017163745.3341787-22-alexei.starovoitov@gmail.com --- kernel/bpf/offload.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/kernel/bpf/offload.c b/kernel/bpf/offload.c index 5a10f40a7831..f7bfff1760cc 100644 --- a/kernel/bpf/offload.c +++ b/kernel/bpf/offload.c @@ -266,7 +266,14 @@ int bpf_prog_dev_bound_init(struct bpf_prog *prog, union bpf_attr *attr) prog->aux->offload_requested = !(attr->prog_flags & BPF_F_XDP_DEV_BOUND_ONLY); down_write(&bpf_devs_lock); - err = __bpf_prog_dev_bound_init(prog, netdev); + /* + * Behind bpf_dev_bound_netdev_unregister() nobody would take the + * program off the device, which goes once the reference is dropped. + */ + if (READ_ONCE(netdev->reg_state) == NETREG_REGISTERED) + err = __bpf_prog_dev_bound_init(prog, netdev); + else + err = -EINVAL; up_write(&bpf_devs_lock); out: