]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 22 Aug 2025 13:44:20 +0000 (15:44 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 22 Aug 2025 13:44:20 +0000 (15:44 +0200)
added patches:
codel-remove-sch-q.qlen-check-before-qdisc_tree_reduce_backlog.patch
sch_drr-make-drr_qlen_notify-idempotent.patch
sch_hfsc-make-hfsc_qlen_notify-idempotent.patch
sch_htb-make-htb_deactivate-idempotent.patch
sch_htb-make-htb_qlen_notify-idempotent.patch
sch_qfq-make-qfq_qlen_notify-idempotent.patch

queue-5.10/codel-remove-sch-q.qlen-check-before-qdisc_tree_reduce_backlog.patch [new file with mode: 0644]
queue-5.10/sch_drr-make-drr_qlen_notify-idempotent.patch [new file with mode: 0644]
queue-5.10/sch_hfsc-make-hfsc_qlen_notify-idempotent.patch [new file with mode: 0644]
queue-5.10/sch_htb-make-htb_deactivate-idempotent.patch [new file with mode: 0644]
queue-5.10/sch_htb-make-htb_qlen_notify-idempotent.patch [new file with mode: 0644]
queue-5.10/sch_qfq-make-qfq_qlen_notify-idempotent.patch [new file with mode: 0644]
queue-5.10/series

diff --git a/queue-5.10/codel-remove-sch-q.qlen-check-before-qdisc_tree_reduce_backlog.patch b/queue-5.10/codel-remove-sch-q.qlen-check-before-qdisc_tree_reduce_backlog.patch
new file mode 100644 (file)
index 0000000..5f3986d
--- /dev/null
@@ -0,0 +1,57 @@
+From 342debc12183b51773b3345ba267e9263bdfaaef Mon Sep 17 00:00:00 2001
+From: Cong Wang <xiyou.wangcong@gmail.com>
+Date: Thu, 3 Apr 2025 14:16:31 -0700
+Subject: codel: remove sch->q.qlen check before qdisc_tree_reduce_backlog()
+
+From: Cong Wang <xiyou.wangcong@gmail.com>
+
+commit 342debc12183b51773b3345ba267e9263bdfaaef upstream.
+
+After making all ->qlen_notify() callbacks idempotent, now it is safe to
+remove the check of qlen!=0 from both fq_codel_dequeue() and
+codel_qdisc_dequeue().
+
+Reported-by: Gerrard Tai <gerrard.tai@starlabs.sg>
+Fixes: 4b549a2ef4be ("fq_codel: Fair Queue Codel AQM")
+Fixes: 76e3cc126bb2 ("codel: Controlled Delay AQM")
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250403211636.166257-1-xiyou.wangcong@gmail.com
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Siddh Raman Pant <siddh.raman.pant@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sched/sch_codel.c    |    5 +----
+ net/sched/sch_fq_codel.c |    6 ++----
+ 2 files changed, 3 insertions(+), 8 deletions(-)
+
+--- a/net/sched/sch_codel.c
++++ b/net/sched/sch_codel.c
+@@ -95,10 +95,7 @@ static struct sk_buff *codel_qdisc_deque
+                           &q->stats, qdisc_pkt_len, codel_get_enqueue_time,
+                           drop_func, dequeue_func);
+-      /* We cant call qdisc_tree_reduce_backlog() if our qlen is 0,
+-       * or HTB crashes. Defer it for next round.
+-       */
+-      if (q->stats.drop_count && sch->q.qlen) {
++      if (q->stats.drop_count) {
+               qdisc_tree_reduce_backlog(sch, q->stats.drop_count, q->stats.drop_len);
+               q->stats.drop_count = 0;
+               q->stats.drop_len = 0;
+--- a/net/sched/sch_fq_codel.c
++++ b/net/sched/sch_fq_codel.c
+@@ -314,10 +314,8 @@ begin:
+       }
+       qdisc_bstats_update(sch, skb);
+       flow->deficit -= qdisc_pkt_len(skb);
+-      /* We cant call qdisc_tree_reduce_backlog() if our qlen is 0,
+-       * or HTB crashes. Defer it for next round.
+-       */
+-      if (q->cstats.drop_count && sch->q.qlen) {
++
++      if (q->cstats.drop_count) {
+               qdisc_tree_reduce_backlog(sch, q->cstats.drop_count,
+                                         q->cstats.drop_len);
+               q->cstats.drop_count = 0;
diff --git a/queue-5.10/sch_drr-make-drr_qlen_notify-idempotent.patch b/queue-5.10/sch_drr-make-drr_qlen_notify-idempotent.patch
new file mode 100644 (file)
index 0000000..cb56767
--- /dev/null
@@ -0,0 +1,66 @@
+From df008598b3a00be02a8051fde89ca0fbc416bd55 Mon Sep 17 00:00:00 2001
+From: Cong Wang <xiyou.wangcong@gmail.com>
+Date: Thu, 3 Apr 2025 14:10:24 -0700
+Subject: sch_drr: make drr_qlen_notify() idempotent
+
+From: Cong Wang <xiyou.wangcong@gmail.com>
+
+commit df008598b3a00be02a8051fde89ca0fbc416bd55 upstream.
+
+drr_qlen_notify() always deletes the DRR class from its active list
+with list_del(), therefore, it is not idempotent and not friendly
+to its callers, like fq_codel_dequeue().
+
+Let's make it idempotent to ease qdisc_tree_reduce_backlog() callers'
+life. Also change other list_del()'s to list_del_init() just to be
+extra safe.
+
+Reported-by: Gerrard Tai <gerrard.tai@starlabs.sg>
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250403211033.166059-3-xiyou.wangcong@gmail.com
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Siddh Raman Pant <siddh.raman.pant@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sched/sch_drr.c |    7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/net/sched/sch_drr.c
++++ b/net/sched/sch_drr.c
+@@ -111,6 +111,7 @@ static int drr_change_class(struct Qdisc
+       if (cl == NULL)
+               return -ENOBUFS;
++      INIT_LIST_HEAD(&cl->alist);
+       cl->common.classid = classid;
+       cl->quantum        = quantum;
+       cl->qdisc          = qdisc_create_dflt(sch->dev_queue,
+@@ -234,7 +235,7 @@ static void drr_qlen_notify(struct Qdisc
+ {
+       struct drr_class *cl = (struct drr_class *)arg;
+-      list_del(&cl->alist);
++      list_del_init(&cl->alist);
+ }
+ static int drr_dump_class(struct Qdisc *sch, unsigned long arg,
+@@ -401,7 +402,7 @@ static struct sk_buff *drr_dequeue(struc
+                       if (unlikely(skb == NULL))
+                               goto out;
+                       if (cl->qdisc->q.qlen == 0)
+-                              list_del(&cl->alist);
++                              list_del_init(&cl->alist);
+                       bstats_update(&cl->bstats, skb);
+                       qdisc_bstats_update(sch, skb);
+@@ -442,7 +443,7 @@ static void drr_reset_qdisc(struct Qdisc
+       for (i = 0; i < q->clhash.hashsize; i++) {
+               hlist_for_each_entry(cl, &q->clhash.hash[i], common.hnode) {
+                       if (cl->qdisc->q.qlen)
+-                              list_del(&cl->alist);
++                              list_del_init(&cl->alist);
+                       qdisc_reset(cl->qdisc);
+               }
+       }
diff --git a/queue-5.10/sch_hfsc-make-hfsc_qlen_notify-idempotent.patch b/queue-5.10/sch_hfsc-make-hfsc_qlen_notify-idempotent.patch
new file mode 100644 (file)
index 0000000..d7896d3
--- /dev/null
@@ -0,0 +1,55 @@
+From 51eb3b65544c9efd6a1026889ee5fb5aa62da3bb Mon Sep 17 00:00:00 2001
+From: Cong Wang <xiyou.wangcong@gmail.com>
+Date: Thu, 3 Apr 2025 14:10:25 -0700
+Subject: sch_hfsc: make hfsc_qlen_notify() idempotent
+
+From: Cong Wang <xiyou.wangcong@gmail.com>
+
+commit 51eb3b65544c9efd6a1026889ee5fb5aa62da3bb upstream.
+
+hfsc_qlen_notify() is not idempotent either and not friendly
+to its callers, like fq_codel_dequeue(). Let's make it idempotent
+to ease qdisc_tree_reduce_backlog() callers' life:
+
+1. update_vf() decreases cl->cl_nactive, so we can check whether it is
+non-zero before calling it.
+
+2. eltree_remove() always removes RB node cl->el_node, but we can use
+   RB_EMPTY_NODE() + RB_CLEAR_NODE() to make it safe.
+
+Reported-by: Gerrard Tai <gerrard.tai@starlabs.sg>
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250403211033.166059-4-xiyou.wangcong@gmail.com
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Siddh Raman Pant <siddh.raman.pant@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sched/sch_hfsc.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/net/sched/sch_hfsc.c
++++ b/net/sched/sch_hfsc.c
+@@ -209,7 +209,10 @@ eltree_insert(struct hfsc_class *cl)
+ static inline void
+ eltree_remove(struct hfsc_class *cl)
+ {
+-      rb_erase(&cl->el_node, &cl->sched->eligible);
++      if (!RB_EMPTY_NODE(&cl->el_node)) {
++              rb_erase(&cl->el_node, &cl->sched->eligible);
++              RB_CLEAR_NODE(&cl->el_node);
++      }
+ }
+ static inline void
+@@ -1230,7 +1233,8 @@ hfsc_qlen_notify(struct Qdisc *sch, unsi
+       /* vttree is now handled in update_vf() so that update_vf(cl, 0, 0)
+        * needs to be called explicitly to remove a class from vttree.
+        */
+-      update_vf(cl, 0, 0);
++      if (cl->cl_nactive)
++              update_vf(cl, 0, 0);
+       if (cl->cl_flags & HFSC_RSC)
+               eltree_remove(cl);
+ }
diff --git a/queue-5.10/sch_htb-make-htb_deactivate-idempotent.patch b/queue-5.10/sch_htb-make-htb_deactivate-idempotent.patch
new file mode 100644 (file)
index 0000000..24513bb
--- /dev/null
@@ -0,0 +1,101 @@
+From 3769478610135e82b262640252d90f6efb05be71 Mon Sep 17 00:00:00 2001
+From: Cong Wang <xiyou.wangcong@gmail.com>
+Date: Mon, 28 Apr 2025 16:29:54 -0700
+Subject: sch_htb: make htb_deactivate() idempotent
+
+From: Cong Wang <xiyou.wangcong@gmail.com>
+
+commit 3769478610135e82b262640252d90f6efb05be71 upstream.
+
+Alan reported a NULL pointer dereference in htb_next_rb_node()
+after we made htb_qlen_notify() idempotent.
+
+It turns out in the following case it introduced some regression:
+
+htb_dequeue_tree():
+  |-> fq_codel_dequeue()
+    |-> qdisc_tree_reduce_backlog()
+      |-> htb_qlen_notify()
+        |-> htb_deactivate()
+  |-> htb_next_rb_node()
+  |-> htb_deactivate()
+
+For htb_next_rb_node(), after calling the 1st htb_deactivate(), the
+clprio[prio]->ptr could be already set to  NULL, which means
+htb_next_rb_node() is vulnerable here.
+
+For htb_deactivate(), although we checked qlen before calling it, in
+case of qlen==0 after qdisc_tree_reduce_backlog(), we may call it again
+which triggers the warning inside.
+
+To fix the issues here, we need to:
+
+1) Make htb_deactivate() idempotent, that is, simply return if we
+   already call it before.
+2) Make htb_next_rb_node() safe against ptr==NULL.
+
+Many thanks to Alan for testing and for the reproducer.
+
+Fixes: 5ba8b837b522 ("sch_htb: make htb_qlen_notify() idempotent")
+Reported-by: Alan J. Wylie <alan@wylie.me.uk>
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Link: https://patch.msgid.link/20250428232955.1740419-2-xiyou.wangcong@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Siddh Raman Pant <siddh.raman.pant@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sched/sch_htb.c |   15 ++++++---------
+ 1 file changed, 6 insertions(+), 9 deletions(-)
+
+--- a/net/sched/sch_htb.c
++++ b/net/sched/sch_htb.c
+@@ -331,7 +331,8 @@ static void htb_add_to_wait_tree(struct
+  */
+ static inline void htb_next_rb_node(struct rb_node **n)
+ {
+-      *n = rb_next(*n);
++      if (*n)
++              *n = rb_next(*n);
+ }
+ /**
+@@ -573,8 +574,8 @@ static inline void htb_activate(struct h
+  */
+ static inline void htb_deactivate(struct htb_sched *q, struct htb_class *cl)
+ {
+-      WARN_ON(!cl->prio_activity);
+-
++      if (!cl->prio_activity)
++              return;
+       htb_deactivate_prios(q, cl);
+       cl->prio_activity = 0;
+ }
+@@ -1173,8 +1174,6 @@ static void htb_qlen_notify(struct Qdisc
+ {
+       struct htb_class *cl = (struct htb_class *)arg;
+-      if (!cl->prio_activity)
+-              return;
+       htb_deactivate(qdisc_priv(sch), cl);
+ }
+@@ -1282,8 +1281,7 @@ static int htb_delete(struct Qdisc *sch,
+       if (cl->parent)
+               cl->parent->children--;
+-      if (cl->prio_activity)
+-              htb_deactivate(q, cl);
++      htb_deactivate(q, cl);
+       if (cl->cmode != HTB_CAN_SEND)
+               htb_safe_rb_erase(&cl->pq_node,
+@@ -1408,8 +1406,7 @@ static int htb_change_class(struct Qdisc
+                       /* turn parent into inner node */
+                       qdisc_purge_queue(parent->leaf.q);
+                       parent_qdisc = parent->leaf.q;
+-                      if (parent->prio_activity)
+-                              htb_deactivate(q, parent);
++                      htb_deactivate(q, parent);
+                       /* remove from evt list because of level change */
+                       if (parent->cmode != HTB_CAN_SEND) {
diff --git a/queue-5.10/sch_htb-make-htb_qlen_notify-idempotent.patch b/queue-5.10/sch_htb-make-htb_qlen_notify-idempotent.patch
new file mode 100644 (file)
index 0000000..a3be0ce
--- /dev/null
@@ -0,0 +1,39 @@
+From 5ba8b837b522d7051ef81bacf3d95383ff8edce5 Mon Sep 17 00:00:00 2001
+From: Cong Wang <xiyou.wangcong@gmail.com>
+Date: Thu, 3 Apr 2025 14:10:23 -0700
+Subject: sch_htb: make htb_qlen_notify() idempotent
+
+From: Cong Wang <xiyou.wangcong@gmail.com>
+
+commit 5ba8b837b522d7051ef81bacf3d95383ff8edce5 upstream.
+
+htb_qlen_notify() always deactivates the HTB class and in fact could
+trigger a warning if it is already deactivated. Therefore, it is not
+idempotent and not friendly to its callers, like fq_codel_dequeue().
+
+Let's make it idempotent to ease qdisc_tree_reduce_backlog() callers'
+life.
+
+Reported-by: Gerrard Tai <gerrard.tai@starlabs.sg>
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250403211033.166059-2-xiyou.wangcong@gmail.com
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Siddh Raman Pant <siddh.raman.pant@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sched/sch_htb.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/sched/sch_htb.c
++++ b/net/sched/sch_htb.c
+@@ -1173,6 +1173,8 @@ static void htb_qlen_notify(struct Qdisc
+ {
+       struct htb_class *cl = (struct htb_class *)arg;
++      if (!cl->prio_activity)
++              return;
+       htb_deactivate(qdisc_priv(sch), cl);
+ }
diff --git a/queue-5.10/sch_qfq-make-qfq_qlen_notify-idempotent.patch b/queue-5.10/sch_qfq-make-qfq_qlen_notify-idempotent.patch
new file mode 100644 (file)
index 0000000..f1d8751
--- /dev/null
@@ -0,0 +1,67 @@
+From 55f9eca4bfe30a15d8656f915922e8c98b7f0728 Mon Sep 17 00:00:00 2001
+From: Cong Wang <xiyou.wangcong@gmail.com>
+Date: Thu, 3 Apr 2025 14:10:26 -0700
+Subject: sch_qfq: make qfq_qlen_notify() idempotent
+
+From: Cong Wang <xiyou.wangcong@gmail.com>
+
+commit 55f9eca4bfe30a15d8656f915922e8c98b7f0728 upstream.
+
+qfq_qlen_notify() always deletes its class from its active list
+with list_del_init() _and_ calls qfq_deactivate_agg() when the whole list
+becomes empty.
+
+To make it idempotent, just skip everything when it is not in the active
+list.
+
+Also change other list_del()'s to list_del_init() just to be extra safe.
+
+Reported-by: Gerrard Tai <gerrard.tai@starlabs.sg>
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250403211033.166059-5-xiyou.wangcong@gmail.com
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Siddh Raman Pant <siddh.raman.pant@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sched/sch_qfq.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/net/sched/sch_qfq.c
++++ b/net/sched/sch_qfq.c
+@@ -354,7 +354,7 @@ static void qfq_deactivate_class(struct
+       struct qfq_aggregate *agg = cl->agg;
+-      list_del(&cl->alist); /* remove from RR queue of the aggregate */
++      list_del_init(&cl->alist); /* remove from RR queue of the aggregate */
+       if (list_empty(&agg->active)) /* agg is now inactive */
+               qfq_deactivate_agg(q, agg);
+ }
+@@ -486,6 +486,7 @@ static int qfq_change_class(struct Qdisc
+       cl->common.classid = classid;
+       cl->deficit = lmax;
++      INIT_LIST_HEAD(&cl->alist);
+       cl->qdisc = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
+                                     classid, NULL);
+@@ -1005,7 +1006,7 @@ static struct sk_buff *agg_dequeue(struc
+       cl->deficit -= (int) len;
+       if (cl->qdisc->q.qlen == 0) /* no more packets, remove from list */
+-              list_del(&cl->alist);
++              list_del_init(&cl->alist);
+       else if (cl->deficit < qdisc_pkt_len(cl->qdisc->ops->peek(cl->qdisc))) {
+               cl->deficit += agg->lmax;
+               list_move_tail(&cl->alist, &agg->active);
+@@ -1437,6 +1438,8 @@ static void qfq_qlen_notify(struct Qdisc
+       struct qfq_sched *q = qdisc_priv(sch);
+       struct qfq_class *cl = (struct qfq_class *)arg;
++      if (list_empty(&cl->alist))
++              return;
+       qfq_deactivate_class(q, cl);
+ }
index ca7fb2d80f2a5aedec77d601b9386d255c65bd99..6df4f99dc493cfdc07cb4576a6c49ccadf3328fa 100644 (file)
@@ -384,3 +384,9 @@ media-ov2659-fix-memory-leaks-in-ov2659_probe.patch
 media-venus-add-a-check-for-packet-size-after-reading-from-shared-memory.patch
 drm-amd-restore-cached-power-limit-during-resume.patch
 net-hsr-reject-hsr-frame-if-skb-can-t-hold-tag.patch
+sch_htb-make-htb_qlen_notify-idempotent.patch
+sch_drr-make-drr_qlen_notify-idempotent.patch
+sch_hfsc-make-hfsc_qlen_notify-idempotent.patch
+sch_qfq-make-qfq_qlen_notify-idempotent.patch
+codel-remove-sch-q.qlen-check-before-qdisc_tree_reduce_backlog.patch
+sch_htb-make-htb_deactivate-idempotent.patch