Skip to content

Commit 30e7249

Browse files
edumazetSasha Levin
authored andcommitted
net_sched: red: fix a race in __red_change()
[ Upstream commit 85a3e0e ] 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: 0c8d13a ("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>
1 parent 6613d44 commit 30e7249

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

net/sched/sch_red.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ static int __red_change(struct Qdisc *sch, struct nlattr **tb,
285285
q->userbits = userbits;
286286
q->limit = ctl->limit;
287287
if (child) {
288-
qdisc_tree_flush_backlog(q->qdisc);
288+
qdisc_purge_queue(q->qdisc);
289289
old_child = q->qdisc;
290290
q->qdisc = child;
291291
}

0 commit comments

Comments
 (0)