summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2025-06-11 11:15:12 +0000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-06-27 11:04:09 +0100
commita1bf6a4e9264a685b0e642994031f9c5aad72414 (patch)
treefe0099fe240ccf8f46fa13493abc6ff4bef248d7 /net
parent4483d8b9127591c60c4eb789d6cab953bc4522a9 (diff)
downloadlinux-a1bf6a4e9264a685b0e642994031f9c5aad72414.tar.gz
linux-a1bf6a4e9264a685b0e642994031f9c5aad72414.tar.bz2
linux-a1bf6a4e9264a685b0e642994031f9c5aad72414.zip
net_sched: red: fix a race in __red_change()
[ Upstream commit 85a3e0ede38450ea3053b8c45d28cf55208409b8 ] Gerrard Tai reported a race condition in RED, whenever SFQ perturb timer fires at the wrong time. The race is as follows: CPU 0 CPU 1 [1]: lock root [2]: qdisc_tree_flush_backlog() [3]: unlock root | | [5]: lock root | [6]: rehash | [7]: qdisc_tree_reduce_backlog() | [4]: qdisc_put() This can be abused to underflow a parent's qlen. Calling qdisc_purge_queue() instead of qdisc_tree_flush_backlog() should fix the race, because all packets will be purged from the qdisc before releasing the lock. Fixes: 0c8d13ac9607 ("net: sched: red: delay destroying child qdisc on replace") Reported-by: Gerrard Tai <gerrard.tai@starlabs.sg> Suggested-by: Gerrard Tai <gerrard.tai@starlabs.sg> Signed-off-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20250611111515.1983366-3-edumazet@google.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_red.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
index 935d90874b1b..1b69b7b90d85 100644
--- a/net/sched/sch_red.c
+++ b/net/sched/sch_red.c
@@ -283,7 +283,7 @@ static int __red_change(struct Qdisc *sch, struct nlattr **tb,
q->userbits = userbits;
q->limit = ctl->limit;
if (child) {
- qdisc_tree_flush_backlog(q->qdisc);
+ qdisc_purge_queue(q->qdisc);
old_child = q->qdisc;
q->qdisc = child;
}