mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
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: 2b3486bc2d ("bpf: Introduce device-bound XDP programs")
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://patch.msgid.link/20261017163745.3341787-22-alexei.starovoitov@gmail.com
This commit is contained in:
parent
8e83d53596
commit
af929bc938
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user