ee3bc829f9
commit 3e337087c3b5805fe0b8a46ba622a962880b5d64 upstream.
Lion says:
-------
In the QFQ scheduler a similar issue to CVE-2023-31436
persists.
Consider the following code in net/sched/sch_qfq.c:
static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch,
struct sk_buff **to_free)
{
unsigned int len = qdisc_pkt_len(skb), gso_segs;
// ...
if (unlikely(cl->agg->lmax < len)) {
pr_debug("qfq: increasing maxpkt from %u to %u for class %u",
cl->agg->lmax, len, cl->common.classid);
err = qfq_change_agg(sch, cl, cl->agg->class_weight, len);
if (err) {
cl->qstats.drops++;
return qdisc_drop(skb, sch, to_free);
}
// ...
}
Similarly to CVE-2023-31436, "lmax" is increased without any bounds
checks according to the packet length "len". Usually this would not
impose a problem because packet sizes are naturally limited.
This is however not the actual packet length, rather the
"qdisc_pkt_len(skb)" which might apply size transformations according to
"struct qdisc_size_table" as created by "qdisc_get_stab()" in
net/sched/sch_api.c if the TCA_STAB option was set when modifying the qdisc.
A user may choose virtually any size using such a table.
As a result the same issue as in CVE-2023-31436 can occur, allowing heap
out-of-bounds read / writes in the kmalloc-8192 cache.
-------
We can create the issue with the following commands:
tc qdisc add dev $DEV root handle 1: stab mtu 2048 tsize 512 mpu 0 \
overhead 999999999 linklayer ethernet qfq
tc class add dev $DEV parent 1: classid 1:1 htb rate 6mbit burst 15k
tc filter add dev $DEV parent 1: matchall classid 1:1
ping -I $DEV 1.1.1.2
This is caused by incorrectly assuming that qdisc_pkt_len() returns a
length within the QFQ_MIN_LMAX < len < QFQ_MAX_LMAX.
Fixes:
|
||
---|---|---|
.. | ||
act_api.c | ||
act_bpf.c | ||
act_connmark.c | ||
act_csum.c | ||
act_gact.c | ||
act_ife.c | ||
act_ipt.c | ||
act_meta_mark.c | ||
act_meta_skbprio.c | ||
act_meta_skbtcindex.c | ||
act_mirred.c | ||
act_nat.c | ||
act_pedit.c | ||
act_police.c | ||
act_sample.c | ||
act_simple.c | ||
act_skbedit.c | ||
act_skbmod.c | ||
act_tunnel_key.c | ||
act_vlan.c | ||
cls_api.c | ||
cls_basic.c | ||
cls_bpf.c | ||
cls_cgroup.c | ||
cls_flow.c | ||
cls_flower.c | ||
cls_fw.c | ||
cls_matchall.c | ||
cls_route.c | ||
cls_rsvp.c | ||
cls_rsvp.h | ||
cls_rsvp6.c | ||
cls_u32.c | ||
em_canid.c | ||
em_cmp.c | ||
em_ipset.c | ||
em_ipt.c | ||
em_meta.c | ||
em_nbyte.c | ||
em_text.c | ||
em_u32.c | ||
ematch.c | ||
Kconfig | ||
Makefile | ||
sch_api.c | ||
sch_atm.c | ||
sch_blackhole.c | ||
sch_cake.c | ||
sch_cbq.c | ||
sch_cbs.c | ||
sch_choke.c | ||
sch_codel.c | ||
sch_drr.c | ||
sch_dsmark.c | ||
sch_etf.c | ||
sch_fifo.c | ||
sch_fq.c | ||
sch_fq_codel.c | ||
sch_generic.c | ||
sch_gred.c | ||
sch_hfsc.c | ||
sch_hhf.c | ||
sch_htb.c | ||
sch_ingress.c | ||
sch_mq.c | ||
sch_mqprio.c | ||
sch_multiq.c | ||
sch_netem.c | ||
sch_pie.c | ||
sch_plug.c | ||
sch_prio.c | ||
sch_qfq.c | ||
sch_red.c | ||
sch_sfb.c | ||
sch_sfq.c | ||
sch_skbprio.c | ||
sch_tbf.c | ||
sch_teql.c |