Thread (8 messages) flat view 8 messages, 5 authors, 14d ago

Re: [PATCH net] net/sched: cls_bpf: reject dev-bound programs bound to a different device

From: Jamal Hadi Salim <jhs@mojatatu.com>
Date: 2026-08-13 08:52:47
Also in: bpf, stable

On Sun, Aug 9, 2026 at 5:44 AM Jamal Hadi Salim [off-list ref] wrote:
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: 6c8dfe21c435 ("cls_bpf: allow attaching programs loaded for specific device")
Fixes: 2b3486bc2d23 ("bpf: Introduce device-bound XDP programs")

cheers,
jamal
quoted hunk ↗ jump to hunk
Reported-by: vega@nebusec.ai
Tested-by: Victor Nogueira <redacted>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
---
 net/sched/cls_bpf.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c
index 001d8c4ebfed..6d19155becc8 100644
--- a/net/sched/cls_bpf.c
+++ b/net/sched/cls_bpf.c
@@ -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;

--
2.34.1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help