* Kernel bug report: unguarded deferred skb_checksum_help() writes corrupt the previously-validated IPv6 fixed header (IPv6 counterpart of commit 6785011f8b16, "ipv4: validate checksum_start before completing checksum")
@ 2026-10-19 8:43 Pranjal Kumar Singh
2026-10-19 8:50 ` Michael S. Tsirkin
2026-10-19 8:54 ` Greg KH
0 siblings, 2 replies; 4+ messages in thread
From: Pranjal Kumar Singh @ 2026-10-19 8:43 UTC (permalink / raw)
To: cve, netdev, Pablo Neira Ayuso, Jozsef Kadlecsik, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Michael S. Tsirkin,
Willem de Bruijn, Paulos Yibelo, openvswitch, stable,
fw@strlen.de
[-- Attachment #1.1: Type: text/plain, Size: 5512 bytes --]
Hello Security Team,
The IPv4 part of this was fixed some time ago in commit 6785011f8b16
("ipv4: validate checksum_start before completing checksum"): a packet
whose virtio_net_hdr csum metadata points its checksum start inside the
IP header makes skb_checksum_help() (the deferred csum completion)
rewrite the header the stack has already validated (fixed checksum
offset-width write at csum_start + csum_offset). The IPv6 paths were
not covered, and they still are not: a 2-patch series mirroring that
commit for IPv4->IPv6, including its remaining not-yet-IPv6-guarded
sinks, is reproduced below and attached as patches/0001 and 0002.
Why this is reachable today
---------------------------
include/linux/virtio_net.h's __virtio_net_hdr_to_skb() only enforces
skb_transport_offset() >= sizeof(struct iphdr) (nh_min_len) for
NEEDS_CSUM -- i.e., for IPv6 packets any csum_start in
[20, sizeof(struct ipv6hdr)) passes admission, sitting inside the fixed
40-byte IPv6 header that the stack has just validated. With TUN (tun
device using IFF_VNET_HDR) or AF_PACKET csum -- the same admission the
virtio/vhost setup uses for guests, and reachable unprivileged --
skb_checksum_help() can then write an attacker-chosen 16-bit value into
the outgoing IPv6 header of a forwarded frame. The write value is
csum_fold over an attacker-built payload and is fully deterministic
(pre-computed in userspace in the reproducer).
Sinks on master (line numbers from c03c1a14507d, "Linux 7.3", checked
2026-10-19):
net/ipv6/ip6_output.c:945 ip6_fragment() unguarded
net/ipv6/netfilter.c:147 br_ip6_fragment() unguarded
(reachable by bridge
refrag in
net/bridge/netfilter/
nf_conntrack_bridge.c:358 and
by Open vSwitch
ovs_fragment()'s IPv6 branch
which calls ip6_fragment())
net/netfilter/xt_CHECKSUM.c:30 checksum_tg() guard is
NFPROTO_IPV4-only, IPv6 falls
through; helper return also
ignored (patch 2)
net/netfilter/nfnetlink_queue.c:678 nf_queue_checksum_help()
checked for ETH_P_IP only,
IPv6 falls through
net/xfrm/xfrm_output.c:826 xfrm_output() same
ETH_P_IP-only gate
The ip6_fragment() side-drop is the direct sibling of the IPv4
ip_do_fragment() check that commit added; xt_CHECKSUM's IPv6 case is
reachable for a v6-only netns since ingress-side -- for instance via
`ip6tables -t mangle POSTROUTING -j CHECKSUM --checksum-fill`, which
finalizes the partial checksum at the sink.
Bug report and evidence
-----------------------
Dear attachments, all under ipv6-csum-start-submission.zip:
- report.txt: detailed writeup with the full admission-gap audit and
the sink table above, impact, and the reproducer output below;
- patches/0000-cover-letter.txt, 0001, 0002: the proposed git-series
(2 patches, drafted against c03c1a14507d);
- poc/poc_ipv6_csum_start.c: a single-file reproducer (as PID 1 in an
initramfs VM it needs no external tools -- netns + veth + tun via
raw netlink, TUN,VNET_HDR, ip6tables via the bundled
ip6tables-legacy, and a packet-over-TUN/AF_PACKET sender); csum
geometry (csum_start=24 = inside the IPv6 fixed header) with a
csum_start=64 falsification control variant;
- poc/build_vm.sh, logs/run-*.log: the two runs, verbatim, from a
QEMU initramfs VM against a real 6.12.38 kernel (no KVM required):
-- control (csum_start=64, past the header) --
[*] emitted frame #1 len=1478 daddr intact: fd:00:00:0c hop_limit=63
[+] control OK: 1 frames, headers intact
Ip6OutForwDatagrams 1
-- evil (csum_start=24, inside the header) --
[!] MUTATED OUTPUT FRAME #1: daddr bits now 4a:32:00:0c
(wire-validated value was fd00:c::= 0c:0c:0c:0c); written
16-bit=4a32 len=1478
[+] BUG CONFIRMED: csum_start=24 < sizeof(struct ipv6hdr)=40:
deferred skb_checksum_help() rewrote the previously VALIDATED
IPv6 header in an EMITTED packet.
Ip6OutForwDatagrams 1
The 4a:32 written into the emitted frame's destination address is the
folded checksum the reproducer predicted before sending; the control
run shows the same code path intact, ruling out ordinary corruption.
Likewise, no CVE for this IPv6 path is known to me as of 2026-10-19;
there is no harm in restoring parity with the IPv4 fix, and following
up with cve@kernel.org after this lands, if you agree.
The proposed fix mirrors commit 6785011f8b16 one sink at a time; the
input-side admission is still the "more work forthcoming" item from
that commit's changelog (its IPv4 work precedes it), and this series
does not attempt to change it -- it only documents that gap in
report.txt for whoever picks it up.
Happy to rework the split (netfilter-only first, or one patch per
sink), or to paste the patches inline if inline is preferred over the
attachment. Testing status: the reproducer was exercised end to end
against the 6.12.38 kernel named above; patches are hand-crafted and
not yet boot-tested as a series.
Let me know if it is eligible for CVE
Thanks,
PRNJL
[-- Attachment #1.2: Type: text/html, Size: 6293 bytes --]
[-- Attachment #2: ipv6-csum-PRNJL.zip --]
[-- Type: application/x-zip-compressed, Size: 26367 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Kernel bug report: unguarded deferred skb_checksum_help() writes corrupt the previously-validated IPv6 fixed header (IPv6 counterpart of commit 6785011f8b16, "ipv4: validate checksum_start before completing checksum")
2026-10-19 8:43 Kernel bug report: unguarded deferred skb_checksum_help() writes corrupt the previously-validated IPv6 fixed header (IPv6 counterpart of commit 6785011f8b16, "ipv4: validate checksum_start before completing checksum") Pranjal Kumar Singh
@ 2026-10-19 8:50 ` Michael S. Tsirkin
[not found] ` <CA+UYBZCEe3C2HuqgZSZ9Xa7MUxCNy=9ckBmA1Kyjmt882ZRQBA@mail.gmail.com>
2026-10-19 8:54 ` Greg KH
1 sibling, 1 reply; 4+ messages in thread
From: Michael S. Tsirkin @ 2026-10-19 8:50 UTC (permalink / raw)
To: Pranjal Kumar Singh
Cc: cve, netdev, Pablo Neira Ayuso, Jozsef Kadlecsik, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Willem de Bruijn,
Paulos Yibelo, openvswitch, stable, fw@strlen.de
On Mon, Oct 19, 2026 at 02:13:04PM +0530, Pranjal Kumar Singh wrote:
> Hello Security Team,
>
> The IPv4 part of this was fixed some time ago in commit 6785011f8b16
> ("ipv4: validate checksum_start before completing checksum"): a packet
> whose virtio_net_hdr csum metadata points its checksum start inside the
> IP header makes skb_checksum_help() (the deferred csum completion)
> rewrite the header the stack has already validated (fixed checksum
> offset-width write at csum_start + csum_offset). The IPv6 paths were
> not covered, and they still are not: a 2-patch series mirroring that
> commit for IPv4->IPv6, including its remaining not-yet-IPv6-guarded
> sinks, is reproduced below and attached as patches/0001 and 0002.
Thanks, I think this has been reported already. Just to clarify, the effect
is just packet header corruption past validation, right?
See [PATCH net-next v2 0/7] more virtio-net csum hardening
for WIP fixes.
--
MST
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Kernel bug report: unguarded deferred skb_checksum_help() writes corrupt the previously-validated IPv6 fixed header (IPv6 counterpart of commit 6785011f8b16, "ipv4: validate checksum_start before completing checksum")
2026-10-19 8:43 Kernel bug report: unguarded deferred skb_checksum_help() writes corrupt the previously-validated IPv6 fixed header (IPv6 counterpart of commit 6785011f8b16, "ipv4: validate checksum_start before completing checksum") Pranjal Kumar Singh
2026-10-19 8:50 ` Michael S. Tsirkin
@ 2026-10-19 8:54 ` Greg KH
1 sibling, 0 replies; 4+ messages in thread
From: Greg KH @ 2026-10-19 8:54 UTC (permalink / raw)
To: Pranjal Kumar Singh
Cc: cve, netdev, Pablo Neira Ayuso, Jozsef Kadlecsik, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Michael S. Tsirkin,
Willem de Bruijn, Paulos Yibelo, openvswitch, stable,
fw@strlen.de
On Mon, Oct 19, 2026 at 02:13:04PM +0530, Pranjal Kumar Singh wrote:
> Bug report and evidence
> -----------------------
> Dear attachments, all under ipv6-csum-start-submission.zip:
For obvious reasons, you don't want us opening binary attachments.
Always submit everything in plain text, as our documentation kindly asks
you to.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Kernel bug report: unguarded deferred skb_checksum_help() writes corrupt the previously-validated IPv6 fixed header (IPv6 counterpart of commit 6785011f8b16, "ipv4: validate checksum_start before completing checksum")
[not found] ` <CA+UYBZCEe3C2HuqgZSZ9Xa7MUxCNy=9ckBmA1Kyjmt882ZRQBA@mail.gmail.com>
@ 2026-10-19 10:09 ` Michael S. Tsirkin
0 siblings, 0 replies; 4+ messages in thread
From: Michael S. Tsirkin @ 2026-10-19 10:09 UTC (permalink / raw)
To: Pranjal Kumar Singh
Cc: cve, netdev, Pablo Neira Ayuso, Jozsef Kadlecsik, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Willem de Bruijn,
Paulos Yibelo, openvswitch, stable, fw@strlen.de
On Mon, Oct 19, 2026 at 02:36:14PM +0530, Pranjal Kumar Singh wrote:
> Yes. One 16-bit csum_fold() write at
> csum_start + csum_offset, always within the packet's own linear data
> (admission's pskb_may_pull(needed) bounds it), so no OOB, no memory
> safety issue and no crash; just a previously-validated header field
> changed after the stack committed to it. With the IPv6 geometry I
> reported (csum_start in [20, 40) slipping past nh_min_len == 20), the
> write lands in the fixed IPv6 header only -- dst/src bytes; version,
> payload length, nexthdr and hop limit (bytes 0-7) are unreachable from
> that geometry -- and the written value is attacker-derivable
> (precomputed csum_fold in the reproducer; wire value matched byte for
> byte, control run intact).
>
> I went through the full v2 series: with 4/7 my geometry is resolved at
> ingress via the mismatch path (Routing-header parse -> csum_start !=
> thoff -> completed before protocol processing), so the observed window
> is closed on the virtio-hdr-tested flows and my sink-side patches are
> superseded for that case. I'll repost them (or thin them further out)
> as a net-next follow-up to your v3 only for the sysctl opt-out case in
> 5/7 (knob off = my geometry is admitted fully intact with
> CHECKSUM_PARTIAL retained and the deferred write happens as before),
> plus the xt_CHECKSUM v6 / nf_queue / xfrm_output family gates, which
> 0/7 doesn't touch.
>
I don't get what this all means What sink side patches? 0/7 of the
patches I posted touches what code? I don't think it makes sense to look
at that sysctl deep in the net stack, if that is what you are saying.
> On Mon, Oct 19, 2026 at 2:20 PM Michael S. Tsirkin <mst@redhat.com> wrote:
>
> On Mon, Oct 19, 2026 at 02:13:04PM +0530, Pranjal Kumar Singh wrote:
> > Hello Security Team,
> >
> > The IPv4 part of this was fixed some time ago in commit 6785011f8b16
> > ("ipv4: validate checksum_start before completing checksum"): a packet
> > whose virtio_net_hdr csum metadata points its checksum start inside the
> > IP header makes skb_checksum_help() (the deferred csum completion)
> > rewrite the header the stack has already validated (fixed checksum
> > offset-width write at csum_start + csum_offset). The IPv6 paths were
> > not covered, and they still are not: a 2-patch series mirroring that
> > commit for IPv4->IPv6, including its remaining not-yet-IPv6-guarded
> > sinks, is reproduced below and attached as patches/0001 and 0002.
>
> Thanks, I think this has been reported already. Just to clarify, the effect
> is just packet header corruption past validation, right?
>
> See [PATCH net-next v2 0/7] more virtio-net csum hardening
> for WIP fixes.
>
> --
> MST
>
>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-10-19 10:09 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-19 8:43 Kernel bug report: unguarded deferred skb_checksum_help() writes corrupt the previously-validated IPv6 fixed header (IPv6 counterpart of commit 6785011f8b16, "ipv4: validate checksum_start before completing checksum") Pranjal Kumar Singh
2026-10-19 8:50 ` Michael S. Tsirkin
[not found] ` <CA+UYBZCEe3C2HuqgZSZ9Xa7MUxCNy=9ckBmA1Kyjmt882ZRQBA@mail.gmail.com>
2026-10-19 10:09 ` Michael S. Tsirkin
2026-10-19 8:54 ` Greg KH
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.