Netdev List
 help / color / mirror / Atom feed
From: sung byeongchan <tjdqudcks0424@naver.com>
To: Pablo Neira Ayuso <pablo@netfilter.org>,
	Florian Westphal <fw@strlen.de>, Phil Sutter <phil@nwl.cc>
Cc: netfilter-devel@vger.kernel.org, netdev@vger.kernel.org,
	stable@vger.kernel.org, "Jakub Kicinski" <kuba@kernel.org>,
	"Jérémy Jean" <Jeremy.Jean@oss.cyber.gouv.fr>,
	Sashiko <netdev-bot+sashiko@kernel.org>,
	성병찬 <tjdqudcks0424@naver.com>
Subject: [PATCH net v2] netfilter: nf_conntrack_reasm: avoid truncating header offsets
Date: Thu,  8 Oct 2026 14:02:25 +0900	[thread overview]
Message-ID: <20261008050225.29543-1-tjdqudcks0424@naver.com> (raw)
In-Reply-To: <20260929090027.200041-1-tjdqudcks0424@naver.com>

From: 성병찬 <tjdqudcks0424@naver.com>

find_prev_fhdr() stores the offset of the previous Next Header field in
an 8-bit variable. A valid IPv6 extension header chain can place that
field at offset 256, causing the value to wrap to zero. Reassembly then
writes the Fragment Header's next-header value to the wrong byte.

Use int for prev_nhoff so the offset is preserved until it is checked by
its consumer.

The same path also passes an unchecked offset to two 16-bit consumers:
frag_queue.nhoffset and skb->transport_header. On the LOCAL_OUT raw path,
a 65536-byte IPv6 packet can place the Fragment Header at offset 65528.
With 16 bytes of skb headroom, skb_set_transport_header() truncates 65544
to 8. In the reproduced path, reassembly subsequently passes -8 as the
unsigned skb_push() length and triggers skb_under_panic().

Reject a previous-header offset that cannot be represented by nhoffset,
and use skb_set_transport_header_careful() to reject a Fragment Header
offset that cannot be represented relative to skb->head.

The prev_nhoff widening was previously posted by Jérémy Jean. This
revision folds it together with the remaining 16-bit checks, as requested
by Pablo Neira Ayuso.

The 16-bit transport-header failure reproduced on three independent
boots, including one run from outer UID 65534 in new user and network
namespaces. With the combined fix, the trigger was rejected safely in
three runs. Short fragments, ordinary IPv6 TCP and UDP, and the earlier
offset-248 and offset-256 cases continued to work.

Fixes: 9fb9cbb1082d ("[NETFILTER]: Add nf_conntrack subsystem.")
Reported-by: Sashiko <netdev-bot+sashiko@kernel.org>
Link: https://lore.kernel.org/netfilter-devel/20260822214012.1028305-2-Jeremy.Jean@oss.cyber.gouv.fr/
Link: https://lore.kernel.org/netfilter-devel/179089937913.434549.5874493628033954656@kernel.org/
Cc: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: 성병찬 <tjdqudcks0424@naver.com>
---
Changes in v2:
- Fold the remaining u16 nhoffset and transport-header checks into the
  prev_nhoff fix, as requested by Pablo Neira Ayuso.
- Add the three-run crash and fixed A/B results.
- Credit Jérémy Jean's earlier posting of the prev_nhoff widening.

 net/ipv6/netfilter/nf_conntrack_reasm.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 599c49bf0a0a..ae25ebc873b0 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -398,7 +398,7 @@ find_prev_fhdr(struct sk_buff *skb, u8 *prevhdrp, int *prevhoff, int *fhoff)
 {
 	u8 nexthdr = ipv6_hdr(skb)->nexthdr;
 	const int netoff = skb_network_offset(skb);
-	u8 prev_nhoff = netoff + offsetof(struct ipv6hdr, nexthdr);
+	int prev_nhoff = netoff + offsetof(struct ipv6hdr, nexthdr);
 	int start = netoff + sizeof(struct ipv6hdr);
 	int len = skb->len - start;
 	u8 prevhdr = NEXTHDR_IPV6;
@@ -474,7 +474,9 @@ int nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user)
 	if (!pskb_may_pull(skb, fhoff + sizeof(*fhdr)))
 		return -ENOMEM;
 
-	skb_set_transport_header(skb, fhoff);
+	if (nhoff != (u16)nhoff ||
+	    !skb_set_transport_header_careful(skb, fhoff))
+		return -EINVAL;
 	hdr = ipv6_hdr(skb);
 	fhdr = (struct frag_hdr *)skb_transport_header(skb);
 
base-commit: 6d25ffca055a77787c21a36b66c253f76239411b
-- 
2.43.0


      parent reply	other threads:[~2026-10-08  5:02 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-29  9:00 [PATCH net] netfilter: nf_conntrack_reasm: avoid truncating header offset tjdqudcks0424
2026-09-29  9:14 ` netdev-bot+sinfo
2026-10-02  0:02 ` netdev-bot+sashiko
2026-10-02  7:42   ` tjdqudcks0424
2026-10-07 22:57     ` Pablo Neira Ayuso
2026-10-08  5:02 ` sung byeongchan [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261008050225.29543-1-tjdqudcks0424@naver.com \
    --to=tjdqudcks0424@naver.com \
    --cc=Jeremy.Jean@oss.cyber.gouv.fr \
    --cc=fw@strlen.de \
    --cc=kuba@kernel.org \
    --cc=netdev-bot+sashiko@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=pablo@netfilter.org \
    --cc=phil@nwl.cc \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox