* [PATCH net v4 0/2] net: prevent partial checksums from modifying IPv4 headers
@ 2026-09-20 0:47 Paulos Yibelo
2026-09-20 0:47 ` [PATCH net v4 1/2] net: validate virtio checksum start after network header Paulos Yibelo
2026-09-20 0:47 ` [PATCH net v4 2/2] ipv4: reject partial checksums covering the IP header Paulos Yibelo
0 siblings, 2 replies; 5+ messages in thread
From: Paulos Yibelo @ 2026-09-20 0:47 UTC (permalink / raw)
To: netdev
Cc: mst, jasowangio, eperezma, xuanzhuo, virtualization, dsahern,
idosch, davem, edumazet, kuba, pabeni, horms, willemb, hannes,
linux-kernel
A TUN or virtio-net user can supply CHECKSUM_PARTIAL metadata whose
checksum start resolves inside the IPv4 header after link-layer headers
are removed. On the IPv4 fragmentation path, skb_checksum_help() may then
modify an IHL which was already parsed and validated. ip_do_fragment()
subsequently trusts the changed IHL and can copy beyond the skb's logical
linear head into emitted IPv4 options.
Patch 1 validates the checksum start relative to skb_network_header().
Patch 2 independently validates and retains the IPv4 header length before
checksum completion.
The issue and this series were reviewed privately. The source reproducer
and complete runtime evidence remain available privately.
Validation included strict checkpatch, focused W=1 builds, a complete
build, two test boots, a legitimate fragmented CHECKSUM_PARTIAL control,
and both forged cases.
Paulos Yibelo (2):
net: validate virtio checksum start after network header
ipv4: reject partial checksums covering the IP header
include/linux/virtio_net.h | 5 +++--
net/ipv4/ip_output.c | 23 +++++++++++++++++------
2 files changed, 20 insertions(+), 8 deletions(-)
base-commit: 9d565b6b72fe3f41fd43636e143072848105189f
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH net v4 1/2] net: validate virtio checksum start after network header
2026-09-20 0:47 [PATCH net v4 0/2] net: prevent partial checksums from modifying IPv4 headers Paulos Yibelo
@ 2026-09-20 0:47 ` Paulos Yibelo
2026-09-20 1:11 ` David Ahern
2026-09-20 0:47 ` [PATCH net v4 2/2] ipv4: reject partial checksums covering the IP header Paulos Yibelo
1 sibling, 1 reply; 5+ messages in thread
From: Paulos Yibelo @ 2026-09-20 0:47 UTC (permalink / raw)
To: netdev
Cc: mst, jasowangio, eperezma, xuanzhuo, virtualization, dsahern,
idosch, davem, edumazet, kuba, pabeni, horms, willemb, hannes,
linux-kernel
__virtio_net_hdr_to_skb() rejects a CHECKSUM_PARTIAL start smaller than an
estimated minimum network-header length. The comparison currently uses the
offset from skb->data rather than the offset from skb_network_header().
For an AF_PACKET frame, skb->data can still point at the Ethernet header
while skb_network_header() points past nested link-layer headers. A
checksum start at the network header can therefore pass, then target byte
zero after those headers are removed.
This does not require a virtual-machine guest. A TUN device with
virtio-net header support can supply the same checksum metadata.
Keep the existing data-relative lower bound and also require checksum
start to follow the estimated minimum relative to skb_network_header().
Fixes: 49d14b54a527 ("net: test for not too small csum_start in virtio_net_hdr_to_skb()")
Reported-by: Paulos Yibelo <habte.yibelo@gmail.com>
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Paulos Yibelo <habte.yibelo@gmail.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
---
Changes in v4:
- State explicitly that a TUN device is sufficient and no guest is required,
as noted by Michael S. Tsirkin. No code changes.
Changes in v3:
- Keep the network-relative comparison on one line for readability, as
requested by David Ahern.
Changes in v2:
- Make nh_min_len an int and remove the casts, as suggested by Michael S.
Tsirkin.
include/linux/virtio_net.h | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
index c381b91..a95ad46 100644
--- a/include/linux/virtio_net.h
+++ b/include/linux/virtio_net.h
@@ -52,7 +52,7 @@ static inline int __virtio_net_hdr_to_skb(struct sk_buff *skb,
const struct virtio_net_hdr *hdr,
bool little_endian, u8 hdr_gso_type)
{
- unsigned int nh_min_len = sizeof(struct iphdr);
+ int nh_min_len = sizeof(struct iphdr);
unsigned int gso_type = 0;
unsigned int thlen = 0;
unsigned int p_off = 0;
@@ -104,7 +104,8 @@ static inline int __virtio_net_hdr_to_skb(struct sk_buff *skb,
if (!skb_partial_csum_set(skb, start, off))
return -EINVAL;
- if (skb_transport_offset(skb) < nh_min_len)
+ if (skb_transport_offset(skb) < nh_min_len ||
+ skb_transport_offset(skb) - skb_network_offset(skb) < nh_min_len)
return -EINVAL;
nh_min_len = skb_transport_offset(skb);
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH net v4 2/2] ipv4: reject partial checksums covering the IP header
2026-09-20 0:47 [PATCH net v4 0/2] net: prevent partial checksums from modifying IPv4 headers Paulos Yibelo
2026-09-20 0:47 ` [PATCH net v4 1/2] net: validate virtio checksum start after network header Paulos Yibelo
@ 2026-09-20 0:47 ` Paulos Yibelo
2026-09-20 1:12 ` David Ahern
1 sibling, 1 reply; 5+ messages in thread
From: Paulos Yibelo @ 2026-09-20 0:47 UTC (permalink / raw)
To: netdev
Cc: mst, jasowangio, eperezma, xuanzhuo, virtualization, dsahern,
idosch, davem, edumazet, kuba, pabeni, horms, willemb, hannes,
linux-kernel
ip_do_fragment() completes a CHECKSUM_PARTIAL skb before reading the IPv4
header length. A virtualization interface can supply a checksum start that
still points inside the IPv4 header after link-layer removal.
This does not require a virtual-machine guest. A TUN device with
virtio-net header support is sufficient to reach this path.
skb_checksum_help() can then change iph->ihl after the packet was parsed
and routed. Fragmentation trusts the changed IHL and can copy beyond the
skb's logical linear head into transmitted IPv4 options.
Read and validate IHL before checksum completion, reject a checksum start
inside that header, retain the validated length, and reacquire iph after
skb_checksum_help().
Fixes: dbd3393c56a8 ("ipv4: add defensive check for CHECKSUM_PARTIAL skbs in ip_fragment")
Reported-by: Paulos Yibelo <habte.yibelo@gmail.com>
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Paulos Yibelo <habte.yibelo@gmail.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
---
Changes in v4:
- State explicitly that a TUN device is sufficient and no guest is required,
as noted by Michael S. Tsirkin. No code changes.
Changes in v3:
- No code changes.
Changes in v2:
- No code changes.
net/ipv4/ip_output.c | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index a24cc8e..ff902a2 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -770,17 +770,29 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
struct ip_frag_state state;
int err = 0;
- /* for offloaded checksums cleanup checksum before fragmentation */
- if (skb->ip_summed == CHECKSUM_PARTIAL &&
- (err = skb_checksum_help(skb)))
- goto fail;
-
/*
* Point into the IP datagram header.
*/
iph = ip_hdr(skb);
+ hlen = iph->ihl * 4;
+ if (unlikely(hlen < sizeof(*iph) || hlen > skb_headlen(skb))) {
+ err = -EINVAL;
+ goto fail;
+ }
+ /* Complete offloaded checksums only after the validated IP header. */
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ if (unlikely(skb_checksum_start_offset(skb) < hlen)) {
+ err = -EINVAL;
+ goto fail;
+ }
+ err = skb_checksum_help(skb);
+ if (err)
+ goto fail;
+ iph = ip_hdr(skb);
+ }
+
mtu = ip_skb_dst_mtu(sk, skb);
if (IPCB(skb)->frag_max_size && IPCB(skb)->frag_max_size < mtu)
mtu = IPCB(skb)->frag_max_size;
@@ -789,7 +801,6 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
* Setup starting values.
*/
- hlen = iph->ihl * 4;
if (mtu < hlen + 8) {
err = -EMSGSIZE;
goto fail;
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net v4 1/2] net: validate virtio checksum start after network header
2026-09-20 0:47 ` [PATCH net v4 1/2] net: validate virtio checksum start after network header Paulos Yibelo
@ 2026-09-20 1:11 ` David Ahern
0 siblings, 0 replies; 5+ messages in thread
From: David Ahern @ 2026-09-20 1:11 UTC (permalink / raw)
To: Paulos Yibelo, netdev
Cc: mst, jasowangio, eperezma, xuanzhuo, virtualization, idosch,
davem, edumazet, kuba, pabeni, horms, willemb, hannes,
linux-kernel
On 9/19/26 6:47 PM, Paulos Yibelo wrote:
> __virtio_net_hdr_to_skb() rejects a CHECKSUM_PARTIAL start smaller than an
> estimated minimum network-header length. The comparison currently uses the
> offset from skb->data rather than the offset from skb_network_header().
>
> For an AF_PACKET frame, skb->data can still point at the Ethernet header
> while skb_network_header() points past nested link-layer headers. A
> checksum start at the network header can therefore pass, then target byte
> zero after those headers are removed.
>
> This does not require a virtual-machine guest. A TUN device with
> virtio-net header support can supply the same checksum metadata.
>
> Keep the existing data-relative lower bound and also require checksum
> start to follow the estimated minimum relative to skb_network_header().
>
> Fixes: 49d14b54a527 ("net: test for not too small csum_start in virtio_net_hdr_to_skb()")
> Reported-by: Paulos Yibelo <habte.yibelo@gmail.com>
> Cc: stable@vger.kernel.org
> Assisted-by: LLM
> Signed-off-by: Paulos Yibelo <habte.yibelo@gmail.com>
> Acked-by: Michael S. Tsirkin <mst@redhat.com>
> ---
> Changes in v4:
> - State explicitly that a TUN device is sufficient and no guest is required,
> as noted by Michael S. Tsirkin. No code changes.
>
> Changes in v3:
> - Keep the network-relative comparison on one line for readability, as
> requested by David Ahern.
>
> Changes in v2:
> - Make nh_min_len an int and remove the casts, as suggested by Michael S.
> Tsirkin.
>
> include/linux/virtio_net.h | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
Reviewed-by: David Ahern <dsahern@kernel.org>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net v4 2/2] ipv4: reject partial checksums covering the IP header
2026-09-20 0:47 ` [PATCH net v4 2/2] ipv4: reject partial checksums covering the IP header Paulos Yibelo
@ 2026-09-20 1:12 ` David Ahern
0 siblings, 0 replies; 5+ messages in thread
From: David Ahern @ 2026-09-20 1:12 UTC (permalink / raw)
To: Paulos Yibelo, netdev
Cc: mst, jasowangio, eperezma, xuanzhuo, virtualization, idosch,
davem, edumazet, kuba, pabeni, horms, willemb, hannes,
linux-kernel
On 9/19/26 6:47 PM, Paulos Yibelo wrote:
> ip_do_fragment() completes a CHECKSUM_PARTIAL skb before reading the IPv4
> header length. A virtualization interface can supply a checksum start that
> still points inside the IPv4 header after link-layer removal.
>
> This does not require a virtual-machine guest. A TUN device with
> virtio-net header support is sufficient to reach this path.
>
> skb_checksum_help() can then change iph->ihl after the packet was parsed
> and routed. Fragmentation trusts the changed IHL and can copy beyond the
> skb's logical linear head into transmitted IPv4 options.
>
> Read and validate IHL before checksum completion, reject a checksum start
> inside that header, retain the validated length, and reacquire iph after
> skb_checksum_help().
>
> Fixes: dbd3393c56a8 ("ipv4: add defensive check for CHECKSUM_PARTIAL skbs in ip_fragment")
> Reported-by: Paulos Yibelo <habte.yibelo@gmail.com>
> Cc: stable@vger.kernel.org
> Assisted-by: LLM
> Signed-off-by: Paulos Yibelo <habte.yibelo@gmail.com>
> Acked-by: Michael S. Tsirkin <mst@redhat.com>
> ---
> Changes in v4:
> - State explicitly that a TUN device is sufficient and no guest is required,
> as noted by Michael S. Tsirkin. No code changes.
>
> Changes in v3:
> - No code changes.
>
> Changes in v2:
> - No code changes.
>
> net/ipv4/ip_output.c | 23 +++++++++++++++++------
> 1 file changed, 17 insertions(+), 6 deletions(-)
>
>
Reviewed-by: David Ahern <dsahern@kernel.org>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-09-20 1:12 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-20 0:47 [PATCH net v4 0/2] net: prevent partial checksums from modifying IPv4 headers Paulos Yibelo
2026-09-20 0:47 ` [PATCH net v4 1/2] net: validate virtio checksum start after network header Paulos Yibelo
2026-09-20 1:11 ` David Ahern
2026-09-20 0:47 ` [PATCH net v4 2/2] ipv4: reject partial checksums covering the IP header Paulos Yibelo
2026-09-20 1:12 ` David Ahern
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®