From: Amery Hung Date: Tue, 29 Apr 2025 19:21:28 +0000 (-0700) Subject: bpf: net_sched: Fix using bpf qdisc as default qdisc X-Git-Tag: v6.16-rc1~132^2~173^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7625645e69454f984f09ea450b9eb1293467aa39;p=thirdparty%2Flinux.git bpf: net_sched: Fix using bpf qdisc as default qdisc Use bpf_try_module_get()/bpf_module_put() instead of try_module_get()/ module_put() when handling default qdisc since users can assign a bpf qdisc to it. To trigger the bug: $ bpftool struct_ops register bpf_qdisc_fq.bpf.o /sys/fs/bpf $ echo bpf_fq > /proc/sys/net/core/default_qdisc Fixes: c8240344956e ("bpf: net_sched: Support implementation of Qdisc_ops in bpf") Signed-off-by: Amery Hung Signed-off-by: Martin KaFai Lau Link: https://patch.msgid.link/20250429192128.3860571-1-ameryhung@gmail.com --- diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index db6330258dda9..c5e3673aadbe7 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -208,7 +208,7 @@ static struct Qdisc_ops *qdisc_lookup_default(const char *name) for (q = qdisc_base; q; q = q->next) { if (!strcmp(name, q->id)) { - if (!try_module_get(q->owner)) + if (!bpf_try_module_get(q, q->owner)) q = NULL; break; } @@ -238,7 +238,7 @@ int qdisc_set_default(const char *name) if (ops) { /* Set new default */ - module_put(default_qdisc_ops->owner); + bpf_module_put(default_qdisc_ops, default_qdisc_ops->owner); default_qdisc_ops = ops; } write_unlock(&qdisc_mod_lock); diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index fc5ef69359dbb..08e0e3aff9763 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -1002,14 +1002,14 @@ struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue, { struct Qdisc *sch; - if (!try_module_get(ops->owner)) { + if (!bpf_try_module_get(ops, ops->owner)) { NL_SET_ERR_MSG(extack, "Failed to increase module reference counter"); return NULL; } sch = qdisc_alloc(dev_queue, ops, extack); if (IS_ERR(sch)) { - module_put(ops->owner); + bpf_module_put(ops, ops->owner); return NULL; } sch->parent = parentid;