]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
net_sched: hfsc: Fix a potential UAF in hfsc_dequeue() too
authorCong Wang <xiyou.wangcong@gmail.com>
Thu, 17 Apr 2025 18:47:31 +0000 (11:47 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 2 May 2025 05:41:15 +0000 (07:41 +0200)
[ Upstream commit 6ccbda44e2cc3d26fd22af54c650d6d5d801addf ]

Similarly to the previous patch, we need to safe guard hfsc_dequeue()
too. But for this one, we don't have a reliable reproducer.

Fixes: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 ("Linux-2.6.12-rc2")
Reported-by: Gerrard Tai <gerrard.tai@starlabs.sg>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/20250417184732.943057-3-xiyou.wangcong@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/sched/sch_hfsc.c

index ed8211c8d1f4c235c742eb4bdcc59fde28382514..aad090fd165b09531a35fc05ee30ac938d465f45 100644 (file)
@@ -1643,10 +1643,16 @@ hfsc_dequeue(struct Qdisc *sch)
                if (cl->qdisc->q.qlen != 0) {
                        /* update ed */
                        next_len = qdisc_peek_len(cl->qdisc);
-                       if (realtime)
-                               update_ed(cl, next_len);
-                       else
-                               update_d(cl, next_len);
+                       /* Check queue length again since some qdisc implementations
+                        * (e.g., netem/codel) might empty the queue during the peek
+                        * operation.
+                        */
+                       if (cl->qdisc->q.qlen != 0) {
+                               if (realtime)
+                                       update_ed(cl, next_len);
+                               else
+                                       update_d(cl, next_len);
+                       }
                } else {
                        /* the class becomes passive */
                        eltree_remove(cl);