* [PATCH net v5 0/2] net/sched: taprio: fix NULL pointer dereference in class dump
@ 2026-04-22 16:19 Weiming Shi
2026-04-22 16:19 ` [PATCH net v5 1/2] " Weiming Shi
2026-04-22 16:19 ` [PATCH net v5 2/2] selftests/tc-testing: add taprio test for class dump after child delete Weiming Shi
0 siblings, 2 replies; 6+ messages in thread
From: Weiming Shi @ 2026-04-22 16:19 UTC (permalink / raw)
To: vinicius.gomes, jhs, jiri
Cc: davem, edumazet, kuba, pabeni, horms, vladimir.oltean, shuah,
xmei5, netdev, linux-kselftest, Weiming Shi
Fix a NULL pointer dereference in taprio_dump_class() reachable by an
unprivileged local user on kernels with unprivileged user namespaces
enabled and CONFIG_NET_SCH_TAPRIO=y. The bug allows a local DoS via a
crafted sequence of taprio child-qdisc graft, delete, and class dump.
Patch 1/2 is the fix: replace NULL entries in q->qdiscs[] with the
global &noop_qdisc singleton so that control-plane dump paths, as well
as the existing NULL guards in the data-plane enqueue/dequeue paths,
cannot deref a NULL child qdisc.
Patch 2/2 is a tdc regression test that drives the graft + delete +
class-dump sequence on a multi-queue netdevsim device. It panics the
vulnerable kernel and passes on the fixed one.
v5: only call qdisc_put(*old) when *old is non-NULL and not
&noop_qdisc (Paolo).
v4: https://lore.kernel.org/netdev/20260416185501.647884-3-bestswngs@gmail.com/
add selftests/tc-testing regression test (patch 2/2) (Jamal).
add Assisted-by tag.
v3: https://lore.kernel.org/netdev/20260414104311.74115-2-bestswngs@gmail.com/
fix broken patch
v2: https://lore.kernel.org/netdev/20260410153902.955227-2-bestswngs@gmail.com/
also update NULL guards in taprio_enqueue() and
taprio_dequeue_from_txq() to avoid qlen/backlog inflation (Paolo).
v1: https://lore.kernel.org/netdev/20260330102904.2677818-5-bestswngs@gmail.com/
Weiming Shi (2):
net/sched: taprio: fix NULL pointer dereference in class dump
selftests/tc-testing: add taprio test for class dump after child
delete
net/sched/sch_taprio.c | 13 ++++++----
.../tc-testing/tc-tests/qdiscs/taprio.json | 26 +++++++++++++++++++
2 files changed, 34 insertions(+), 5 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH net v5 1/2] net/sched: taprio: fix NULL pointer dereference in class dump 2026-04-22 16:19 [PATCH net v5 0/2] net/sched: taprio: fix NULL pointer dereference in class dump Weiming Shi @ 2026-04-22 16:19 ` Weiming Shi 2026-04-26 10:59 ` Jamal Hadi Salim 2026-04-22 16:19 ` [PATCH net v5 2/2] selftests/tc-testing: add taprio test for class dump after child delete Weiming Shi 1 sibling, 1 reply; 6+ messages in thread From: Weiming Shi @ 2026-04-22 16:19 UTC (permalink / raw) To: vinicius.gomes, jhs, jiri Cc: davem, edumazet, kuba, pabeni, horms, vladimir.oltean, shuah, xmei5, netdev, linux-kselftest, Weiming Shi When a TAPRIO child qdisc is deleted via RTM_DELQDISC, taprio_graft() is called with new == NULL and stores NULL into q->qdiscs[cl - 1]. Subsequent RTM_GETTCLASS dump operations walk all classes via taprio_walk() and call taprio_dump_class(), which calls taprio_leaf() returning the NULL pointer, then dereferences it to read child->handle, causing a kernel NULL pointer dereference. The bug is reachable with namespace-scoped CAP_NET_ADMIN on any kernel with CONFIG_NET_SCH_TAPRIO enabled. On systems with unprivileged user namespaces enabled, an unprivileged local user can trigger a kernel panic by creating a taprio qdisc inside a new network namespace, grafting an explicit child qdisc, deleting it, and requesting a class dump. The RTM_GETTCLASS dump itself requires no capability. Oops: general protection fault, probably for non-canonical address 0xdffffc0000000007: 0000 [#1] SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000038-0x000000000000003f] RIP: 0010:taprio_dump_class (net/sched/sch_taprio.c:2478) Call Trace: <TASK> tc_fill_tclass (net/sched/sch_api.c:1966) qdisc_class_dump (net/sched/sch_api.c:2326) taprio_walk (net/sched/sch_taprio.c:2514) tc_dump_tclass_qdisc (net/sched/sch_api.c:2352) tc_dump_tclass_root (net/sched/sch_api.c:2370) tc_dump_tclass (net/sched/sch_api.c:2431) rtnl_dumpit (net/core/rtnetlink.c:6864) netlink_dump (net/netlink/af_netlink.c:2325) rtnetlink_rcv_msg (net/core/rtnetlink.c:6959) netlink_rcv_skb (net/netlink/af_netlink.c:2550) </TASK> Fix this by substituting &noop_qdisc when new is NULL in taprio_graft(), a common pattern used by other qdiscs (e.g., multiq_graft()) to ensure the q->qdiscs[] slots are never NULL. This makes control-plane dump paths safe without requiring individual NULL checks. Since the data-plane paths (taprio_enqueue and taprio_dequeue_from_txq) previously had explicit NULL guards that would drop/skip the packet cleanly, update those checks to test for &noop_qdisc instead. Without this, packets would reach taprio_enqueue_one() which increments the root qdisc's qlen and backlog before calling the child's enqueue; noop_qdisc drops the packet but those counters are never rolled back, permanently inflating the root qdisc's statistics. After this change *old can be a valid qdisc, NULL, or &noop_qdisc. Only call qdisc_put(*old) in the first case to avoid decreasing noop_qdisc's refcount, which was never increased. Fixes: 665338b2a7a0 ("net/sched: taprio: dump class stats for the actual q->qdiscs[]") Reported-by: Xiang Mei <xmei5@asu.edu> Signed-off-by: Weiming Shi <bestswngs@gmail.com> Assisted-by: Claude:claude-opus-4-6 --- net/sched/sch_taprio.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c index 8e37528119506..a7daf34593e07 100644 --- a/net/sched/sch_taprio.c +++ b/net/sched/sch_taprio.c @@ -634,7 +634,7 @@ static int taprio_enqueue(struct sk_buff *skb, struct Qdisc *sch, queue = skb_get_queue_mapping(skb); child = q->qdiscs[queue]; - if (unlikely(!child)) + if (unlikely(child == &noop_qdisc)) return qdisc_drop(skb, sch, to_free); if (taprio_skb_exceeds_queue_max_sdu(sch, skb)) { @@ -717,7 +717,7 @@ static struct sk_buff *taprio_dequeue_from_txq(struct Qdisc *sch, int txq, int len; u8 tc; - if (unlikely(!child)) + if (unlikely(child == &noop_qdisc)) return NULL; if (TXTIME_ASSIST_IS_ENABLED(q->flags)) @@ -2183,6 +2183,9 @@ static int taprio_graft(struct Qdisc *sch, unsigned long cl, if (!dev_queue) return -EINVAL; + if (!new) + new = &noop_qdisc; + if (dev->flags & IFF_UP) dev_deactivate(dev, false); @@ -2196,14 +2199,14 @@ static int taprio_graft(struct Qdisc *sch, unsigned long cl, *old = q->qdiscs[cl - 1]; if (FULL_OFFLOAD_IS_ENABLED(q->flags)) { WARN_ON_ONCE(dev_graft_qdisc(dev_queue, new) != *old); - if (new) + if (new != &noop_qdisc) qdisc_refcount_inc(new); - if (*old) + if (*old && *old != &noop_qdisc) qdisc_put(*old); } q->qdiscs[cl - 1] = new; - if (new) + if (new != &noop_qdisc) new->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; if (dev->flags & IFF_UP) -- 2.43.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH net v5 1/2] net/sched: taprio: fix NULL pointer dereference in class dump 2026-04-22 16:19 ` [PATCH net v5 1/2] " Weiming Shi @ 2026-04-26 10:59 ` Jamal Hadi Salim 2026-04-26 13:01 ` Weiming Shi 0 siblings, 1 reply; 6+ messages in thread From: Jamal Hadi Salim @ 2026-04-26 10:59 UTC (permalink / raw) To: Weiming Shi Cc: vinicius.gomes, jiri, davem, edumazet, kuba, pabeni, horms, vladimir.oltean, shuah, xmei5, netdev, linux-kselftest On Wed, Apr 22, 2026 at 12:20 PM Weiming Shi <bestswngs@gmail.com> wrote: > > When a TAPRIO child qdisc is deleted via RTM_DELQDISC, taprio_graft() > is called with new == NULL and stores NULL into q->qdiscs[cl - 1]. > Subsequent RTM_GETTCLASS dump operations walk all classes via > taprio_walk() and call taprio_dump_class(), which calls taprio_leaf() > returning the NULL pointer, then dereferences it to read child->handle, > causing a kernel NULL pointer dereference. > > The bug is reachable with namespace-scoped CAP_NET_ADMIN on any kernel > with CONFIG_NET_SCH_TAPRIO enabled. On systems with unprivileged user > namespaces enabled, an unprivileged local user can trigger a kernel > panic by creating a taprio qdisc inside a new network namespace, > grafting an explicit child qdisc, deleting it, and requesting a class > dump. The RTM_GETTCLASS dump itself requires no capability. > > Oops: general protection fault, probably for non-canonical address 0xdffffc0000000007: 0000 [#1] SMP KASAN NOPTI > KASAN: null-ptr-deref in range [0x0000000000000038-0x000000000000003f] > RIP: 0010:taprio_dump_class (net/sched/sch_taprio.c:2478) > Call Trace: > <TASK> > tc_fill_tclass (net/sched/sch_api.c:1966) > qdisc_class_dump (net/sched/sch_api.c:2326) > taprio_walk (net/sched/sch_taprio.c:2514) > tc_dump_tclass_qdisc (net/sched/sch_api.c:2352) > tc_dump_tclass_root (net/sched/sch_api.c:2370) > tc_dump_tclass (net/sched/sch_api.c:2431) > rtnl_dumpit (net/core/rtnetlink.c:6864) > netlink_dump (net/netlink/af_netlink.c:2325) > rtnetlink_rcv_msg (net/core/rtnetlink.c:6959) > netlink_rcv_skb (net/netlink/af_netlink.c:2550) > </TASK> > > Fix this by substituting &noop_qdisc when new is NULL in > taprio_graft(), a common pattern used by other qdiscs (e.g., > multiq_graft()) to ensure the q->qdiscs[] slots are never NULL. > This makes control-plane dump paths safe without requiring individual > NULL checks. > > Since the data-plane paths (taprio_enqueue and taprio_dequeue_from_txq) > previously had explicit NULL guards that would drop/skip the packet > cleanly, update those checks to test for &noop_qdisc instead. Without > this, packets would reach taprio_enqueue_one() which increments the root > qdisc's qlen and backlog before calling the child's enqueue; noop_qdisc > drops the packet but those counters are never rolled back, permanently > inflating the root qdisc's statistics. > > After this change *old can be a valid qdisc, NULL, or &noop_qdisc. > Only call qdisc_put(*old) in the first case to avoid decreasing > noop_qdisc's refcount, which was never increased. > > Fixes: 665338b2a7a0 ("net/sched: taprio: dump class stats for the actual q->qdiscs[]") > Reported-by: Xiang Mei <xmei5@asu.edu> > Signed-off-by: Weiming Shi <bestswngs@gmail.com> > Assisted-by: Claude:claude-opus-4-6 Acked-by: Jamal Hadi Salim <jhs@mojatatu.com> Please add Tested-by: if you tested it with the tdc patch in 2/2 cheers, jamal > --- > net/sched/sch_taprio.c | 13 ++++++++----- > 1 file changed, 8 insertions(+), 5 deletions(-) > > diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c > index 8e37528119506..a7daf34593e07 100644 > --- a/net/sched/sch_taprio.c > +++ b/net/sched/sch_taprio.c > @@ -634,7 +634,7 @@ static int taprio_enqueue(struct sk_buff *skb, struct Qdisc *sch, > queue = skb_get_queue_mapping(skb); > > child = q->qdiscs[queue]; > - if (unlikely(!child)) > + if (unlikely(child == &noop_qdisc)) > return qdisc_drop(skb, sch, to_free); > > if (taprio_skb_exceeds_queue_max_sdu(sch, skb)) { > @@ -717,7 +717,7 @@ static struct sk_buff *taprio_dequeue_from_txq(struct Qdisc *sch, int txq, > int len; > u8 tc; > > - if (unlikely(!child)) > + if (unlikely(child == &noop_qdisc)) > return NULL; > > if (TXTIME_ASSIST_IS_ENABLED(q->flags)) > @@ -2183,6 +2183,9 @@ static int taprio_graft(struct Qdisc *sch, unsigned long cl, > if (!dev_queue) > return -EINVAL; > > + if (!new) > + new = &noop_qdisc; > + > if (dev->flags & IFF_UP) > dev_deactivate(dev, false); > > @@ -2196,14 +2199,14 @@ static int taprio_graft(struct Qdisc *sch, unsigned long cl, > *old = q->qdiscs[cl - 1]; > if (FULL_OFFLOAD_IS_ENABLED(q->flags)) { > WARN_ON_ONCE(dev_graft_qdisc(dev_queue, new) != *old); > - if (new) > + if (new != &noop_qdisc) > qdisc_refcount_inc(new); > - if (*old) > + if (*old && *old != &noop_qdisc) > qdisc_put(*old); > } > > q->qdiscs[cl - 1] = new; > - if (new) > + if (new != &noop_qdisc) > new->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; > > if (dev->flags & IFF_UP) > -- > 2.43.0 > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH net v5 1/2] net/sched: taprio: fix NULL pointer dereference in class dump 2026-04-26 10:59 ` Jamal Hadi Salim @ 2026-04-26 13:01 ` Weiming Shi 0 siblings, 0 replies; 6+ messages in thread From: Weiming Shi @ 2026-04-26 13:01 UTC (permalink / raw) To: Jamal Hadi Salim Cc: vinicius.gomes, jiri, davem, edumazet, kuba, pabeni, horms, vladimir.oltean, shuah, xmei5, netdev, linux-kselftest On 26-04-26 06:59, Jamal Hadi Salim wrote: > On Wed, Apr 22, 2026 at 12:20 PM Weiming Shi <bestswngs@gmail.com> wrote: > > > > When a TAPRIO child qdisc is deleted via RTM_DELQDISC, taprio_graft() > > is called with new == NULL and stores NULL into q->qdiscs[cl - 1]. > > Subsequent RTM_GETTCLASS dump operations walk all classes via > > taprio_walk() and call taprio_dump_class(), which calls taprio_leaf() > > returning the NULL pointer, then dereferences it to read child->handle, > > causing a kernel NULL pointer dereference. > > > > The bug is reachable with namespace-scoped CAP_NET_ADMIN on any kernel > > with CONFIG_NET_SCH_TAPRIO enabled. On systems with unprivileged user > > namespaces enabled, an unprivileged local user can trigger a kernel > > panic by creating a taprio qdisc inside a new network namespace, > > grafting an explicit child qdisc, deleting it, and requesting a class > > dump. The RTM_GETTCLASS dump itself requires no capability. > > > > Oops: general protection fault, probably for non-canonical address 0xdffffc0000000007: 0000 [#1] SMP KASAN NOPTI > > KASAN: null-ptr-deref in range [0x0000000000000038-0x000000000000003f] > > RIP: 0010:taprio_dump_class (net/sched/sch_taprio.c:2478) > > Call Trace: > > <TASK> > > tc_fill_tclass (net/sched/sch_api.c:1966) > > qdisc_class_dump (net/sched/sch_api.c:2326) > > taprio_walk (net/sched/sch_taprio.c:2514) > > tc_dump_tclass_qdisc (net/sched/sch_api.c:2352) > > tc_dump_tclass_root (net/sched/sch_api.c:2370) > > tc_dump_tclass (net/sched/sch_api.c:2431) > > rtnl_dumpit (net/core/rtnetlink.c:6864) > > netlink_dump (net/netlink/af_netlink.c:2325) > > rtnetlink_rcv_msg (net/core/rtnetlink.c:6959) > > netlink_rcv_skb (net/netlink/af_netlink.c:2550) > > </TASK> > > > > Fix this by substituting &noop_qdisc when new is NULL in > > taprio_graft(), a common pattern used by other qdiscs (e.g., > > multiq_graft()) to ensure the q->qdiscs[] slots are never NULL. > > This makes control-plane dump paths safe without requiring individual > > NULL checks. > > > > Since the data-plane paths (taprio_enqueue and taprio_dequeue_from_txq) > > previously had explicit NULL guards that would drop/skip the packet > > cleanly, update those checks to test for &noop_qdisc instead. Without > > this, packets would reach taprio_enqueue_one() which increments the root > > qdisc's qlen and backlog before calling the child's enqueue; noop_qdisc > > drops the packet but those counters are never rolled back, permanently > > inflating the root qdisc's statistics. > > > > After this change *old can be a valid qdisc, NULL, or &noop_qdisc. > > Only call qdisc_put(*old) in the first case to avoid decreasing > > noop_qdisc's refcount, which was never increased. > > > > Fixes: 665338b2a7a0 ("net/sched: taprio: dump class stats for the actual q->qdiscs[]") > > Reported-by: Xiang Mei <xmei5@asu.edu> > > Signed-off-by: Weiming Shi <bestswngs@gmail.com> > > Assisted-by: Claude:claude-opus-4-6 > > Acked-by: Jamal Hadi Salim <jhs@mojatatu.com> > > Please add Tested-by: if you tested it with the tdc patch in 2/2 > > cheers, > jamal Tested-by: Weiming Shi <bestswngs@gmail.com> Thanks, Weiming Shi > > --- > > net/sched/sch_taprio.c | 13 ++++++++----- > > 1 file changed, 8 insertions(+), 5 deletions(-) > > > > diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c > > index 8e37528119506..a7daf34593e07 100644 > > --- a/net/sched/sch_taprio.c > > +++ b/net/sched/sch_taprio.c > > @@ -634,7 +634,7 @@ static int taprio_enqueue(struct sk_buff *skb, struct Qdisc *sch, > > queue = skb_get_queue_mapping(skb); > > > > child = q->qdiscs[queue]; > > - if (unlikely(!child)) > > + if (unlikely(child == &noop_qdisc)) > > return qdisc_drop(skb, sch, to_free); > > > > if (taprio_skb_exceeds_queue_max_sdu(sch, skb)) { > > @@ -717,7 +717,7 @@ static struct sk_buff *taprio_dequeue_from_txq(struct Qdisc *sch, int txq, > > int len; > > u8 tc; > > > > - if (unlikely(!child)) > > + if (unlikely(child == &noop_qdisc)) > > return NULL; > > > > if (TXTIME_ASSIST_IS_ENABLED(q->flags)) > > @@ -2183,6 +2183,9 @@ static int taprio_graft(struct Qdisc *sch, unsigned long cl, > > if (!dev_queue) > > return -EINVAL; > > > > + if (!new) > > + new = &noop_qdisc; > > + > > if (dev->flags & IFF_UP) > > dev_deactivate(dev, false); > > > > @@ -2196,14 +2199,14 @@ static int taprio_graft(struct Qdisc *sch, unsigned long cl, > > *old = q->qdiscs[cl - 1]; > > if (FULL_OFFLOAD_IS_ENABLED(q->flags)) { > > WARN_ON_ONCE(dev_graft_qdisc(dev_queue, new) != *old); > > - if (new) > > + if (new != &noop_qdisc) > > qdisc_refcount_inc(new); > > - if (*old) > > + if (*old && *old != &noop_qdisc) > > qdisc_put(*old); > > } > > > > q->qdiscs[cl - 1] = new; > > - if (new) > > + if (new != &noop_qdisc) > > new->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; > > > > if (dev->flags & IFF_UP) > > -- > > 2.43.0 > > ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH net v5 2/2] selftests/tc-testing: add taprio test for class dump after child delete 2026-04-22 16:19 [PATCH net v5 0/2] net/sched: taprio: fix NULL pointer dereference in class dump Weiming Shi 2026-04-22 16:19 ` [PATCH net v5 1/2] " Weiming Shi @ 2026-04-22 16:19 ` Weiming Shi 2026-04-26 11:00 ` Jamal Hadi Salim 1 sibling, 1 reply; 6+ messages in thread From: Weiming Shi @ 2026-04-22 16:19 UTC (permalink / raw) To: vinicius.gomes, jhs, jiri Cc: davem, edumazet, kuba, pabeni, horms, vladimir.oltean, shuah, xmei5, netdev, linux-kselftest, Weiming Shi Add a regression test for the NULL pointer dereference fixed in the previous commit. Before the fix, taprio_graft() stored NULL into q->qdiscs[cl - 1] when an explicitly grafted child qdisc was deleted via RTM_DELQDISC; the next RTM_GETTCLASS dump then crashed the kernel in taprio_dump_class() while reading child->handle. The test installs a taprio root qdisc on a multi-queue netdevsim device, grafts a pfifo child onto class 8001:1, deletes that child, and then performs a class dump. On a fixed kernel the dump succeeds and all eight taprio classes are listed; on an unpatched kernel the class dump crashes, which surfaces as a test failure. Signed-off-by: Weiming Shi <bestswngs@gmail.com> Assisted-by: Claude:claude-opus-4-6 --- .../tc-testing/tc-tests/qdiscs/taprio.json | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/taprio.json b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/taprio.json index 557fb074acf0c..cd19d05925e40 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/taprio.json +++ b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/taprio.json @@ -302,5 +302,31 @@ "$TC qdisc del dev $ETH root", "echo \"1\" > /sys/bus/netdevsim/del_device" ] + }, + { + "id": "c7e1", + "name": "Class dump after graft and delete of explicit child qdisc", + "category": [ + "qdisc", + "taprio" + ], + "plugins": { + "requires": "nsPlugin" + }, + "setup": [ + "echo \"1 1 8\" > /sys/bus/netdevsim/new_device", + "$TC qdisc replace dev $ETH handle 8001: parent root taprio num_tc 8 map 0 1 2 3 4 5 6 7 queues 1@0 1@1 1@2 1@3 1@4 1@5 1@6 1@7 base-time 0 sched-entry S ff 20000000 clockid CLOCK_TAI", + "$TC qdisc add dev $ETH parent 8001:1 handle 8002: pfifo", + "$TC qdisc del dev $ETH parent 8001:1 handle 8002:" + ], + "cmdUnderTest": "$TC class show dev $ETH", + "expExitCode": "0", + "verifyCmd": "$TC class show dev $ETH", + "matchPattern": "class taprio 8001:[0-9]+ root", + "matchCount": "8", + "teardown": [ + "$TC qdisc del dev $ETH root", + "echo \"1\" > /sys/bus/netdevsim/del_device" + ] } ] -- 2.43.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH net v5 2/2] selftests/tc-testing: add taprio test for class dump after child delete 2026-04-22 16:19 ` [PATCH net v5 2/2] selftests/tc-testing: add taprio test for class dump after child delete Weiming Shi @ 2026-04-26 11:00 ` Jamal Hadi Salim 0 siblings, 0 replies; 6+ messages in thread From: Jamal Hadi Salim @ 2026-04-26 11:00 UTC (permalink / raw) To: Weiming Shi Cc: vinicius.gomes, jiri, davem, edumazet, kuba, pabeni, horms, vladimir.oltean, shuah, xmei5, netdev, linux-kselftest On Wed, Apr 22, 2026 at 12:20 PM Weiming Shi <bestswngs@gmail.com> wrote: > > Add a regression test for the NULL pointer dereference fixed in the > previous commit. Before the fix, taprio_graft() stored NULL into > q->qdiscs[cl - 1] when an explicitly grafted child qdisc was deleted > via RTM_DELQDISC; the next RTM_GETTCLASS dump then crashed the kernel > in taprio_dump_class() while reading child->handle. > > The test installs a taprio root qdisc on a multi-queue netdevsim > device, grafts a pfifo child onto class 8001:1, deletes that child, > and then performs a class dump. On a fixed kernel the dump succeeds > and all eight taprio classes are listed; on an unpatched kernel the > class dump crashes, which surfaces as a test failure. > > Signed-off-by: Weiming Shi <bestswngs@gmail.com> > Assisted-by: Claude:claude-opus-4-6 Acked-by: Jamal Hadi Salim <jhs@mojatatu.com> cheers, jamal > --- > .../tc-testing/tc-tests/qdiscs/taprio.json | 26 +++++++++++++++++++ > 1 file changed, 26 insertions(+) > > diff --git a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/taprio.json b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/taprio.json > index 557fb074acf0c..cd19d05925e40 100644 > --- a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/taprio.json > +++ b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/taprio.json > @@ -302,5 +302,31 @@ > "$TC qdisc del dev $ETH root", > "echo \"1\" > /sys/bus/netdevsim/del_device" > ] > + }, > + { > + "id": "c7e1", > + "name": "Class dump after graft and delete of explicit child qdisc", > + "category": [ > + "qdisc", > + "taprio" > + ], > + "plugins": { > + "requires": "nsPlugin" > + }, > + "setup": [ > + "echo \"1 1 8\" > /sys/bus/netdevsim/new_device", > + "$TC qdisc replace dev $ETH handle 8001: parent root taprio num_tc 8 map 0 1 2 3 4 5 6 7 queues 1@0 1@1 1@2 1@3 1@4 1@5 1@6 1@7 base-time 0 sched-entry S ff 20000000 clockid CLOCK_TAI", > + "$TC qdisc add dev $ETH parent 8001:1 handle 8002: pfifo", > + "$TC qdisc del dev $ETH parent 8001:1 handle 8002:" > + ], > + "cmdUnderTest": "$TC class show dev $ETH", > + "expExitCode": "0", > + "verifyCmd": "$TC class show dev $ETH", > + "matchPattern": "class taprio 8001:[0-9]+ root", > + "matchCount": "8", > + "teardown": [ > + "$TC qdisc del dev $ETH root", > + "echo \"1\" > /sys/bus/netdevsim/del_device" > + ] > } > ] > -- > 2.43.0 > ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-04-26 13:01 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-04-22 16:19 [PATCH net v5 0/2] net/sched: taprio: fix NULL pointer dereference in class dump Weiming Shi 2026-04-22 16:19 ` [PATCH net v5 1/2] " Weiming Shi 2026-04-26 10:59 ` Jamal Hadi Salim 2026-04-26 13:01 ` Weiming Shi 2026-04-22 16:19 ` [PATCH net v5 2/2] selftests/tc-testing: add taprio test for class dump after child delete Weiming Shi 2026-04-26 11:00 ` Jamal Hadi Salim
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox