summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Hemminger <stephen@networkplumber.org>2026-05-09 20:03:25 +0300
committerPaolo Abeni <pabeni@redhat.com>2026-05-14 12:41:30 +0300
commite8be7cdedc41ff28876d66b566770929d03acbb8 (patch)
tree2f4c97c44d47a06ed767b41138aae3db7f510bce
parent675f6f1968a6710f357ac2ab65b0cf6180b8f400 (diff)
downloadlinux-e8be7cdedc41ff28876d66b566770929d03acbb8.tar.xz
net/sched: netem: handle multi-segment skb in corruption
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>
-rw-r--r--net/sched/sch_netem.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 7570bcb10a15..1e9de2ba8891 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -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)) {