Commit ea6b8928 authored by Stephen Hemminger's avatar Stephen Hemminger Committed by Wang Liang
Browse files

sch/netem: fix use after free in netem_dequeue

stable inclusion
from stable-v5.10.226
commit 98c75d76187944296068d685dfd8a1e9fd8c4fdc
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IARX29
CVE: CVE-2024-46800

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=98c75d76187944296068d685dfd8a1e9fd8c4fdc



--------------------------------

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: 50612537 ("netem: fix classful handling")
Reported-by: default avatarBudimir Markovic <markovicbudimir@gmail.com>
Signed-off-by: default avatarStephen Hemminger <stephen@networkplumber.org>
Link: https://patch.msgid.link/20240901182438.4992-1-stephen@networkplumber.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarWang Liang <wangliang74@huawei.com>
parent 42340f1c
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -722,11 +722,10 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch)

				err = qdisc_enqueue(skb, q->qdisc, &to_free);
				kfree_skb_list(to_free);
				if (err != NET_XMIT_SUCCESS &&
				    net_xmit_drop_count(err)) {
				if (err != NET_XMIT_SUCCESS) {
					if (net_xmit_drop_count(err))
						qdisc_qstats_drop(sch);
					qdisc_tree_reduce_backlog(sch, 1,
								  pkt_len);
					qdisc_tree_reduce_backlog(sch, 1, pkt_len);
				}
				goto tfifo_dequeue;
			}