mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 03:35:32 -04:00
net/sched: cls_bpf: reject dev-bound programs bound to a different device
cls_bpf_prog_from_efd() obtained a SCHED_CLS program via
bpf_prog_get_type_dev() but never verified that a device-bound (offloaded)
program's bound netdev matches the TC netdev the classifier is being
attached to. This let a program loaded with prog_ifindex for device A be
attached via cls_bpf + skip_sw to device B; deleting device A then
destroyed the program's offload state while it was still attached to
device B, triggering a netdevsim WARN (panic with panic_on_warn=1).
Mirror the XDP attach path (net/core/dev.c) and reject the attach with
-EINVAL when a dev-bound program's bound device does not match the
target device.
Fixes: 2b3486bc2d ("bpf: Introduce device-bound XDP programs")
Reported-by: vega@nebusec.ai
Tested-by: Victor Nogueira <victor@mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://patch.msgid.link/20260809094418.901607-1-jhs@mojatatu.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
committed by
Paolo Abeni
parent
2bb155e921
commit
120977e2c0
@@ -374,7 +374,8 @@ static int cls_bpf_prog_from_ops(struct nlattr **tb, struct cls_bpf_prog *prog)
|
||||
}
|
||||
|
||||
static int cls_bpf_prog_from_efd(struct nlattr **tb, struct cls_bpf_prog *prog,
|
||||
u32 gen_flags, const struct tcf_proto *tp)
|
||||
u32 gen_flags, const struct tcf_proto *tp,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct bpf_prog *fp;
|
||||
char *name = NULL;
|
||||
@@ -388,6 +389,19 @@ static int cls_bpf_prog_from_efd(struct nlattr **tb, struct cls_bpf_prog *prog,
|
||||
if (IS_ERR(fp))
|
||||
return PTR_ERR(fp);
|
||||
|
||||
if (bpf_prog_is_dev_bound(fp->aux)) {
|
||||
struct tcf_block *block = tp->chain->block;
|
||||
struct net_device *dev;
|
||||
|
||||
dev = block->q ? qdisc_dev(block->q) : NULL;
|
||||
if (!dev || !bpf_offload_dev_match(fp, dev)) {
|
||||
NL_SET_ERR_MSG(extack,
|
||||
"Program is bound to a different device");
|
||||
bpf_prog_put(fp);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (tb[TCA_BPF_NAME]) {
|
||||
name = nla_memdup(tb[TCA_BPF_NAME], GFP_KERNEL);
|
||||
if (!name) {
|
||||
@@ -492,7 +506,7 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb,
|
||||
prog->gen_flags = gen_flags;
|
||||
|
||||
ret = is_bpf ? cls_bpf_prog_from_ops(tb, prog) :
|
||||
cls_bpf_prog_from_efd(tb, prog, gen_flags, tp);
|
||||
cls_bpf_prog_from_efd(tb, prog, gen_flags, tp, extack);
|
||||
if (ret < 0)
|
||||
goto errout_idr;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user