[PATCH net-next 5/5] net/sched: netem: handle multi-segment skb in corruption
From: Stephen Hemminger
Date: Fri Apr 03 2026 - 18:54:13 EST
The packet corruption code only flipped bits in the linear
header portion of the skb, skipping corruption when
skb_headlen() was zero.
Use skb_header_pointer() and skb_store_bits() to access the
full packet data, allowing any bit in the packet to be
corrupted regardless of how the skb is laid out.
Replaces d64cb81dcbd5 ("net/sched: sch_netem: fix
out-of-bounds access in packet corruption") with a more
general solution.
Signed-off-by: Stephen Hemminger <stephen@xxxxxxxxxxxxxxxxxx>
---
net/sched/sch_netem.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 6dc1ba8e999b..9b5731a8cd15 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -525,10 +525,18 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
goto finish_segs;
}
- if (skb_headlen(skb))
- skb->data[get_random_u32_below(skb_headlen(skb))] ^=
- 1 << get_random_u32_below(8);
- q->xstats.corrupted++;
+ if (skb->len > 0) {
+ unsigned int offset = get_random_u32_below(skb->len);
+ u8 *ptr, val;
+
+ /* handle multi-segment skb's */
+ ptr = skb_header_pointer(skb, offset, 1, &val);
+ if (ptr) {
+ val = *ptr ^ (1 << get_random_u32_below(8));
+ skb_store_bits(skb, offset, &val, 1);
+ }
+ q->xstats.corrupted++;
+ }
}
if (unlikely(q->t_len >= sch->limit)) {
--
2.53.0