summaryrefslogtreecommitdiff
path: root/net/sched
diff options
context:
space:
mode:
authorStephen Hemminger <stephen@networkplumber.org>2024-09-01 21:16:07 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-09-12 12:10:16 +0300
commitdb2c235682913a63054e741fe4e19645fdf2d68e (patch)
treed313a885d4eeecd24abcd33cd2be1fcd17636901 /net/sched
parent5ca5b389fddfe4ce3a698cbc1321fac3d8e3e5b1 (diff)
downloadlinux-db2c235682913a63054e741fe4e19645fdf2d68e.tar.xz
sch/netem: fix use after free in netem_dequeue
commit 3b3a2a9c6349e25a025d2330f479bc33a6ccb54a upstream. If netem_dequeue() enqueues packet to inner qdisc and that qdisc returns __NET_XMIT_STOLEN. The packet is dropped but qdisc_tree_reduce_backlog() is not called to update the parent's q.qlen, leading to the similar use-after-free as Commit e04991a48dbaf382 ("netem: fix return value if duplicate enqueue fails") Commands to trigger KASAN UaF: ip link add type dummy ip link set lo up ip link set dummy0 up tc qdisc add dev lo parent root handle 1: drr tc filter add dev lo parent 1: basic classid 1:1 tc class add dev lo classid 1:1 drr tc qdisc add dev lo parent 1:1 handle 2: netem tc qdisc add dev lo parent 2: handle 3: drr tc filter add dev lo parent 3: basic classid 3:1 action mirred egress redirect dev dummy0 tc class add dev lo classid 3:1 drr ping -c1 -W0.01 localhost # Trigger bug tc class del dev lo classid 1:1 tc class add dev lo classid 1:1 drr ping -c1 -W0.01 localhost # UaF Fixes: 50612537e9ab ("netem: fix classful handling") Reported-by: Budimir Markovic <markovicbudimir@gmail.com> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org> Link: https://patch.msgid.link/20240901182438.4992-1-stephen@networkplumber.org Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net/sched')
-rw-r--r--net/sched/sch_netem.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index a18b24c125f4..0eba06613dcd 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -733,11 +733,10 @@ deliver:
err = qdisc_enqueue(skb, q->qdisc, &to_free);
kfree_skb_list(to_free);
- if (err != NET_XMIT_SUCCESS &&
- net_xmit_drop_count(err)) {
- qdisc_qstats_drop(sch);
- qdisc_tree_reduce_backlog(sch, 1,
- pkt_len);
+ if (err != NET_XMIT_SUCCESS) {
+ if (net_xmit_drop_count(err))
+ qdisc_qstats_drop(sch);
+ qdisc_tree_reduce_backlog(sch, 1, pkt_len);
}
goto tfifo_dequeue;
}