]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net/sched: netem: handle multi-segment skb in corruption
authorStephen Hemminger <stephen@networkplumber.org>
Sat, 9 May 2026 17:03:25 +0000 (10:03 -0700)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 14 May 2026 09:41:30 +0000 (11:41 +0200)
The packet corruption code only flipped bits in the linear
header portion of the skb, skipping corruption when
skb_headlen() was zero.

Linearize the whole skb if necessary before corruption.
Extends d64cb81dcbd5 ("net/sched: sch_netem: fix out-of-bounds access
in packet corruption") with a more general solution.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Link: https://patch.msgid.link/20260509171123.307549-5-stephen@networkplumber.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
net/sched/sch_netem.c

index 7570bcb10a1542aa1e3762d3a793604238d32079..1e9de2ba88915729248a2bb54f879feb95fc7ef7 100644 (file)
@@ -513,16 +513,17 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
                        qdisc_qstats_drop(sch);
                        goto finish_segs;
                }
-               if (skb->ip_summed == CHECKSUM_PARTIAL &&
-                   skb_checksum_help(skb)) {
+               if (skb_linearize(skb) ||
+                   (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb))) {
                        qdisc_drop(skb, sch, to_free);
                        skb = NULL;
                        goto finish_segs;
                }
 
-               if (skb_headlen(skb))
-                       skb->data[get_random_u32_below(skb_headlen(skb))] ^=
-                               1 << get_random_u32_below(8);
+               if (skb->len) {
+                       u32 offset = get_random_u32_below(skb->len);
+                       skb->data[offset] ^= 1 << get_random_u32_below(8);
+               }
        }
 
        if (unlikely(sch->q.qlen >= sch->limit)) {