From: Greg Kroah-Hartman Date: Fri, 22 Aug 2025 13:44:20 +0000 (+0200) Subject: 5.10-stable patches X-Git-Tag: v6.16.3~42 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=da54059abca5c6e67fadadc3d6277b823edd0dfa;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches 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 --- 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 index 0000000000..5f3986daec --- /dev/null +++ b/queue-5.10/codel-remove-sch-q.qlen-check-before-qdisc_tree_reduce_backlog.patch @@ -0,0 +1,57 @@ +From 342debc12183b51773b3345ba267e9263bdfaaef Mon Sep 17 00:00:00 2001 +From: Cong Wang +Date: Thu, 3 Apr 2025 14:16:31 -0700 +Subject: codel: remove sch->q.qlen check before qdisc_tree_reduce_backlog() + +From: Cong Wang + +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 +Fixes: 4b549a2ef4be ("fq_codel: Fair Queue Codel AQM") +Fixes: 76e3cc126bb2 ("codel: Controlled Delay AQM") +Signed-off-by: Cong Wang +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250403211636.166257-1-xiyou.wangcong@gmail.com +Acked-by: Jamal Hadi Salim +Signed-off-by: Paolo Abeni +Signed-off-by: Siddh Raman Pant +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..cb567671ef --- /dev/null +++ b/queue-5.10/sch_drr-make-drr_qlen_notify-idempotent.patch @@ -0,0 +1,66 @@ +From df008598b3a00be02a8051fde89ca0fbc416bd55 Mon Sep 17 00:00:00 2001 +From: Cong Wang +Date: Thu, 3 Apr 2025 14:10:24 -0700 +Subject: sch_drr: make drr_qlen_notify() idempotent + +From: Cong Wang + +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 +Signed-off-by: Cong Wang +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250403211033.166059-3-xiyou.wangcong@gmail.com +Acked-by: Jamal Hadi Salim +Signed-off-by: Paolo Abeni +Signed-off-by: Siddh Raman Pant +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..d7896d3385 --- /dev/null +++ b/queue-5.10/sch_hfsc-make-hfsc_qlen_notify-idempotent.patch @@ -0,0 +1,55 @@ +From 51eb3b65544c9efd6a1026889ee5fb5aa62da3bb Mon Sep 17 00:00:00 2001 +From: Cong Wang +Date: Thu, 3 Apr 2025 14:10:25 -0700 +Subject: sch_hfsc: make hfsc_qlen_notify() idempotent + +From: Cong Wang + +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 +Signed-off-by: Cong Wang +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250403211033.166059-4-xiyou.wangcong@gmail.com +Acked-by: Jamal Hadi Salim +Signed-off-by: Paolo Abeni +Signed-off-by: Siddh Raman Pant +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..24513bbdc4 --- /dev/null +++ b/queue-5.10/sch_htb-make-htb_deactivate-idempotent.patch @@ -0,0 +1,101 @@ +From 3769478610135e82b262640252d90f6efb05be71 Mon Sep 17 00:00:00 2001 +From: Cong Wang +Date: Mon, 28 Apr 2025 16:29:54 -0700 +Subject: sch_htb: make htb_deactivate() idempotent + +From: Cong Wang + +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 +Signed-off-by: Cong Wang +Link: https://patch.msgid.link/20250428232955.1740419-2-xiyou.wangcong@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Siddh Raman Pant +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..a3be0cec79 --- /dev/null +++ b/queue-5.10/sch_htb-make-htb_qlen_notify-idempotent.patch @@ -0,0 +1,39 @@ +From 5ba8b837b522d7051ef81bacf3d95383ff8edce5 Mon Sep 17 00:00:00 2001 +From: Cong Wang +Date: Thu, 3 Apr 2025 14:10:23 -0700 +Subject: sch_htb: make htb_qlen_notify() idempotent + +From: Cong Wang + +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 +Signed-off-by: Cong Wang +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250403211033.166059-2-xiyou.wangcong@gmail.com +Acked-by: Jamal Hadi Salim +Signed-off-by: Paolo Abeni +Signed-off-by: Siddh Raman Pant +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..f1d87518a8 --- /dev/null +++ b/queue-5.10/sch_qfq-make-qfq_qlen_notify-idempotent.patch @@ -0,0 +1,67 @@ +From 55f9eca4bfe30a15d8656f915922e8c98b7f0728 Mon Sep 17 00:00:00 2001 +From: Cong Wang +Date: Thu, 3 Apr 2025 14:10:26 -0700 +Subject: sch_qfq: make qfq_qlen_notify() idempotent + +From: Cong Wang + +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 +Signed-off-by: Cong Wang +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250403211033.166059-5-xiyou.wangcong@gmail.com +Acked-by: Jamal Hadi Salim +Signed-off-by: Paolo Abeni +Signed-off-by: Siddh Raman Pant +Signed-off-by: Greg Kroah-Hartman +--- + 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); + } + diff --git a/queue-5.10/series b/queue-5.10/series index ca7fb2d80f..6df4f99dc4 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -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