* [PATCH nft] netfilter: nft_inner: Fix IPv6 inner_thoff desync
@ 2026-05-10 13:19 Yizhou Zhao
2026-05-11 12:39 ` Fernando Fernandez Mancera
0 siblings, 1 reply; 4+ messages in thread
From: Yizhou Zhao @ 2026-05-10 13:19 UTC (permalink / raw)
To: netfilter-devel
Cc: Pablo Neira Ayuso, Florian Westphal, Phil Sutter, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman, stable,
Yuxiang Yang, Xuewei Feng, Qi Li, Ke Xu, Yizhou Zhao
In nft_inner_parse_l2l3(), when processing inner IPv6 packets, ipv6_find_hdr()
correctly computes the transport header offset traversing all extension headers,
but the result is immediately overwritten with nhoff + sizeof(_ip6h) (40 bytes),
which only accounts for the IPv6 base header. This creates a desync between
inner_thoff (wrong — points to extension header start) and l4proto (correct
— e.g., IPPROTO_TCP), enabling transport header forgery and potential firewall
bypass. This issue was found and reproduced with the assistance of GLM 5.1 from
Z.ai, and exists up to Linux 7.1, affecting stable versions from Linux 6.2.
File: net/netfilter/nft_inner.c
Function: nft_inner_parse_l2l3()
```c
thoff = nhoff;
l4proto = ipv6_find_hdr(pkt->skb, &thoff, -1, &fragoff, &fh_flags);
if (l4proto < 0 || thoff > U16_MAX)
return -1;
if (fragoff == 0) {
thoff = nhoff + sizeof(_ip6h); // BUG: overwrites correct thoff
ctx->inner_thoff = thoff; // stores WRONG offset
ctx->l4proto = l4proto;
}
```
For comparison, the normal (non-inner) IPv6 path correctly preserves
ipv6_find_hdr()'s result. Removing the incorrect overwrite ensures
that ipv6_find_hdr()’s calculated transport header offset is preserved,
thereby fixing the desynchronization.
Fixes: 3a07327d10a09 ("netfilter: nft_inner: support for inner tunnel header matching")
Reported-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
Reported-by: Yuxiang Yang <yangyx22@mails.tsinghua.edu.cn>
Reported-by: Xuewei Feng <fengxw06@126.com>
Reported-by: Qi Li <qli01@tsinghua.edu.cn>
Reported-by: Ke Xu <xuke@tsinghua.edu.cn>
Reported-by: GLM 5.1 from Z.ai
Signed-off-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
---
net/netfilter/nft_inner.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/net/netfilter/nft_inner.c b/net/netfilter/nft_inner.c
index c4569d4b9..1b3e7a976 100644
--- a/net/netfilter/nft_inner.c
+++ b/net/netfilter/nft_inner.c
@@ -163,7 +163,6 @@ static int nft_inner_parse_l2l3(const struct nft_inner *priv,
return -1;
if (fragoff == 0) {
- thoff = nhoff + sizeof(_ip6h);
ctx->flags |= NFT_PAYLOAD_CTX_INNER_TH;
ctx->inner_thoff = thoff;
ctx->l4proto = l4proto;
--
2.43.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH nft] netfilter: nft_inner: Fix IPv6 inner_thoff desync
2026-05-10 13:19 [PATCH nft] netfilter: nft_inner: Fix IPv6 inner_thoff desync Yizhou Zhao
@ 2026-05-11 12:39 ` Fernando Fernandez Mancera
2026-05-11 13:37 ` [PATCH v2 " Yizhou Zhao
0 siblings, 1 reply; 4+ messages in thread
From: Fernando Fernandez Mancera @ 2026-05-11 12:39 UTC (permalink / raw)
To: Yizhou Zhao, netfilter-devel
Cc: Pablo Neira Ayuso, Florian Westphal, Phil Sutter, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman, stable,
Yuxiang Yang, Xuewei Feng, Qi Li, Ke Xu
On 5/10/26 3:19 PM, Yizhou Zhao wrote:
> In nft_inner_parse_l2l3(), when processing inner IPv6 packets, ipv6_find_hdr()
> correctly computes the transport header offset traversing all extension headers,
> but the result is immediately overwritten with nhoff + sizeof(_ip6h) (40 bytes),
> which only accounts for the IPv6 base header. This creates a desync between
> inner_thoff (wrong — points to extension header start) and l4proto (correct
> — e.g., IPPROTO_TCP), enabling transport header forgery and potential firewall
> bypass. This issue was found and reproduced with the assistance of GLM 5.1 from
> Z.ai, and exists up to Linux 7.1, affecting stable versions from Linux 6.2.
>
I don't think there is need to mention the model here. Please use the
Assisted-by tag instead.
> File: net/netfilter/nft_inner.c
> Function: nft_inner_parse_l2l3()
>
> ```c
> thoff = nhoff;
> l4proto = ipv6_find_hdr(pkt->skb, &thoff, -1, &fragoff, &fh_flags);
> if (l4proto < 0 || thoff > U16_MAX)
> return -1;
> if (fragoff == 0) {
> thoff = nhoff + sizeof(_ip6h); // BUG: overwrites correct thoff
> ctx->inner_thoff = thoff; // stores WRONG offset
> ctx->l4proto = l4proto;
> }
> ```
>
I do not think this is relevant in the commit message.
> For comparison, the normal (non-inner) IPv6 path correctly preserves
> ipv6_find_hdr()'s result. Removing the incorrect overwrite ensures
> that ipv6_find_hdr()’s calculated transport header offset is preserved,
> thereby fixing the desynchronization.
>
The solution makes sense to me. Thanks!
> Fixes: 3a07327d10a09 ("netfilter: nft_inner: support for inner tunnel header matching")
Please stick to a 12 characters long commit hash. Make sure that
checkpatch.pl script passes.
> Reported-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
> Reported-by: Yuxiang Yang <yangyx22@mails.tsinghua.edu.cn>
> Reported-by: Xuewei Feng <fengxw06@126.com>
> Reported-by: Qi Li <qli01@tsinghua.edu.cn>
> Reported-by: Ke Xu <xuke@tsinghua.edu.cn>
> Reported-by: GLM 5.1 from Z.ai
This isn't correct. It should be Assisted-by tag instead.
Thanks,
Fernando.
> Signed-off-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
> ---
> net/netfilter/nft_inner.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/net/netfilter/nft_inner.c b/net/netfilter/nft_inner.c
> index c4569d4b9..1b3e7a976 100644
> --- a/net/netfilter/nft_inner.c
> +++ b/net/netfilter/nft_inner.c
> @@ -163,7 +163,6 @@ static int nft_inner_parse_l2l3(const struct nft_inner *priv,
> return -1;
>
> if (fragoff == 0) {
> - thoff = nhoff + sizeof(_ip6h);
> ctx->flags |= NFT_PAYLOAD_CTX_INNER_TH;
> ctx->inner_thoff = thoff;
> ctx->l4proto = l4proto;
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2 nft] netfilter: nft_inner: Fix IPv6 inner_thoff desync
2026-05-11 12:39 ` Fernando Fernandez Mancera
@ 2026-05-11 13:37 ` Yizhou Zhao
2026-05-11 16:27 ` Fernando Fernandez Mancera
0 siblings, 1 reply; 4+ messages in thread
From: Yizhou Zhao @ 2026-05-11 13:37 UTC (permalink / raw)
To: fmancera
Cc: davem, edumazet, fengxw06, fw, horms, kuba, netfilter-devel,
pabeni, pablo, phil, qli01, stable, xuke, yangyx22, zhaoyz24
Thank you for your suggestions. Here's the v2 version of our patch.
In nft_inner_parse_l2l3(), when processing inner IPv6 packets,
ipv6_find_hdr() correctly computes the transport header offset
traversing all extension headers, but the result is immediately
overwritten with nhoff + sizeof(_ip6h) (40 bytes), which only
accounts for the IPv6 base header. This creates a desync between
inner_thoff (wrong — points to extension header start) and l4proto
(correct — e.g., IPPROTO_TCP), enabling transport header forgery
and potential firewall bypass. This issue affects stable versions
from Linux 6.2.
For comparison, the normal (non-inner) IPv6 path correctly
preserves ipv6_find_hdr()'s result. Removing the incorrect overwrite
ensures that ipv6_find_hdr()'s calculated transport header offset is
preserved, thereby fixing the desynchronization.
Fixes: 3a07327d10a0 ("netfilter: nft_inner: support for inner tunnel header matching")
Reported-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
Reported-by: Yuxiang Yang <yangyx22@mails.tsinghua.edu.cn>
Reported-by: Xuewei Feng <fengxw06@126.com>
Reported-by: Qi Li <qli01@tsinghua.edu.cn>
Reported-by: Ke Xu <xuke@tsinghua.edu.cn>
Assisted-by: GLM:5.1 Z.ai
Signed-off-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
---
net/netfilter/nft_inner.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/net/netfilter/nft_inner.c b/net/netfilter/nft_inner.c
index c4569d4b9..1b3e7a976 100644
--- a/net/netfilter/nft_inner.c
+++ b/net/netfilter/nft_inner.c
@@ -163,7 +163,6 @@ static int nft_inner_parse_l2l3(const struct nft_inner *priv,
return -1;
if (fragoff == 0) {
- thoff = nhoff + sizeof(_ip6h);
ctx->flags |= NFT_PAYLOAD_CTX_INNER_TH;
ctx->inner_thoff = thoff;
ctx->l4proto = l4proto;
--
2.43.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v2 nft] netfilter: nft_inner: Fix IPv6 inner_thoff desync
2026-05-11 13:37 ` [PATCH v2 " Yizhou Zhao
@ 2026-05-11 16:27 ` Fernando Fernandez Mancera
0 siblings, 0 replies; 4+ messages in thread
From: Fernando Fernandez Mancera @ 2026-05-11 16:27 UTC (permalink / raw)
To: Yizhou Zhao
Cc: davem, edumazet, fengxw06, fw, horms, kuba, netfilter-devel,
pabeni, pablo, phil, qli01, stable, xuke, yangyx22
On 5/11/26 3:37 PM, Yizhou Zhao wrote:
> Thank you for your suggestions. Here's the v2 version of our patch.
>
> In nft_inner_parse_l2l3(), when processing inner IPv6 packets,
> ipv6_find_hdr() correctly computes the transport header offset
> traversing all extension headers, but the result is immediately
> overwritten with nhoff + sizeof(_ip6h) (40 bytes), which only
> accounts for the IPv6 base header. This creates a desync between
> inner_thoff (wrong — points to extension header start) and l4proto
> (correct — e.g., IPPROTO_TCP), enabling transport header forgery
> and potential firewall bypass. This issue affects stable versions
> from Linux 6.2.
>
> For comparison, the normal (non-inner) IPv6 path correctly
> preserves ipv6_find_hdr()'s result. Removing the incorrect overwrite
> ensures that ipv6_find_hdr()'s calculated transport header offset is
> preserved, thereby fixing the desynchronization.
>
> Fixes: 3a07327d10a0 ("netfilter: nft_inner: support for inner tunnel header matching")
> Reported-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
> Reported-by: Yuxiang Yang <yangyx22@mails.tsinghua.edu.cn>
> Reported-by: Xuewei Feng <fengxw06@126.com>
> Reported-by: Qi Li <qli01@tsinghua.edu.cn>
> Reported-by: Ke Xu <xuke@tsinghua.edu.cn>
> Assisted-by: GLM:5.1 Z.ai
> Signed-off-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
> ---
Please could you submit the patch as a new submission rather than a
reply to the old one?
In addition, the correct target tree is nf.git so use [PATCH nf]
instead, thanks!
> net/netfilter/nft_inner.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/net/netfilter/nft_inner.c b/net/netfilter/nft_inner.c
> index c4569d4b9..1b3e7a976 100644
> --- a/net/netfilter/nft_inner.c
> +++ b/net/netfilter/nft_inner.c
> @@ -163,7 +163,6 @@ static int nft_inner_parse_l2l3(const struct nft_inner *priv,
> return -1;
>
> if (fragoff == 0) {
> - thoff = nhoff + sizeof(_ip6h);
> ctx->flags |= NFT_PAYLOAD_CTX_INNER_TH;
> ctx->inner_thoff = thoff;
> ctx->l4proto = l4proto;
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-05-11 16:27 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-10 13:19 [PATCH nft] netfilter: nft_inner: Fix IPv6 inner_thoff desync Yizhou Zhao
2026-05-11 12:39 ` Fernando Fernandez Mancera
2026-05-11 13:37 ` [PATCH v2 " Yizhou Zhao
2026-05-11 16:27 ` Fernando Fernandez Mancera
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox