summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorVictor Nogueira <victor@mojatatu.com>2025-04-25 19:07:06 -0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-05-09 09:50:42 +0200
commit2e7093c7a8aba5d4f8809f271488e5babe75e202 (patch)
tree46a17336c67b06366c1093eb36a8e77641b6de53 /net
parent26e75716b94d6ff9be5ea07d63675c4d189f30b4 (diff)
downloadlinux-2e7093c7a8aba5d4f8809f271488e5babe75e202.tar.gz
linux-2e7093c7a8aba5d4f8809f271488e5babe75e202.tar.bz2
linux-2e7093c7a8aba5d4f8809f271488e5babe75e202.zip
net_sched: hfsc: Fix a UAF vulnerability in class with netem as child qdisc
[ Upstream commit 141d34391abbb315d68556b7c67ad97885407547 ] As described in Gerrard's report [1], we have a UAF case when an hfsc class has a netem child qdisc. The crux of the issue is that hfsc is assuming that checking for cl->qdisc->q.qlen == 0 guarantees that it hasn't inserted the class in the vttree or eltree (which is not true for the netem duplicate case). This patch checks the n_active class variable to make sure that the code won't insert the class in the vttree or eltree twice, catering for the reentrant case. [1] https://lore.kernel.org/netdev/CAHcdcOm+03OD2j6R0=YHKqmy=VgJ8xEOKuP6c7mSgnp-TEJJbw@mail.gmail.com/ Fixes: 37d9cf1a3ce3 ("sched: Fix detection of empty queues in child qdiscs") Reported-by: Gerrard Tai <gerrard.tai@starlabs.sg> Acked-by: Jamal Hadi Salim <jhs@mojatatu.com> Signed-off-by: Victor Nogueira <victor@mojatatu.com> Link: https://patch.msgid.link/20250425220710.3964791-3-victor@mojatatu.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'net')
-rw-r--r--net/sched/sch_hfsc.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 5bb4ab9941d6..1c857dc95e4f 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1565,7 +1565,7 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free)
return err;
}
- if (first) {
+ if (first && !cl->cl_nactive) {
if (cl->cl_flags & HFSC_RSC)
init_ed(cl, len);
if (cl->cl_flags & HFSC_FSC)