From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wr1-f43.google.com (mail-wr1-f43.google.com [209.85.221.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D8DF7395DBF for ; Fri, 9 Oct 2026 16:26:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.43 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791563200; cv=none; b=i5MACr/OaYp13fLlO+u7UCN/SNhn5MxB1SJJhzf4oBWOhGyHgSTmdxanEFn5c6nxYwGsZOAQrOZO8KsZTF1saLz30hqizTbXcm1jA8vkGkfAsBixLA4rdo3Yzng2G0Occ2LU6NaWRLkid93XDpyb1oBNCsIA0Az1S7QZVucj+HI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791563200; c=relaxed/simple; bh=z8LVxDwXNisEDg9XRjD9l5cNR4q4YDySjviXXc/lnQE=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=ot2K4Cyw/BubrKfP8IwWZmpWluH6XiBh/F3AEfrZx9wXhCT8oMEVR8VCsx+yDgHXTVA3ORCHz5nSxrxemKfjHliWUwGXecHGphIzsXp5ktBZdgrIqr7pamXCl4x3q+cQU47fCQalpp+jpPRXZmfO4I2HNywVQQiKEr7kK98BNtM= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=bxiKyY09; arc=none smtp.client-ip=209.85.221.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="bxiKyY09" Received: by mail-wr1-f43.google.com with SMTP id ffacd0b85a97d-48af27fe287so614f8f.0 for ; Fri, 09 Oct 2026 09:26:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1791563189; x=1792167989; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=Ckizy139Yx68MapGfbyuMco76+jqL/TiZ1vLBTM9150=; b=bxiKyY09W2A5BA9exft9roeyERw+dW5dIIhz81IwB+W3asI0+rhE80y37a4gw3SpcQ ENdSmJ4aM6PA9AwXtxvBE+FoBn+vayBhGDg1J8XKNMt7meK3sogD3RbQf2pVPH3bkHcq qoVl3vzsoYgwXRnBgC1sB3eiyqfwd6qlWo6g5WdwnniZt+jW6qGqj66zJS1OA7pi8Ove nE5HR/eqwh7U+6lkHjWddTvWDumdoOOsRlH7Ozmch87f+T2/tBAzRRm0jB54zRm02jwE j5c1Tnt04BHiDOdQJRSrjXL84+Mtu+/4/fmh2jZdU26Gbnc3DCA3VDp2J/WOj9FrLxNT /tPg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1791563189; x=1792167989; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Ckizy139Yx68MapGfbyuMco76+jqL/TiZ1vLBTM9150=; b=HkneedLZ0a77RmwIElbQTRKrzZ8YQCkeFviVQ0OG4/DmZUb/unQR74Y41z5Gd6b67x VgY/MLIkGC5oSsyP8BfU6xdismAZoM5jxrWsTu6OJfoCSFlTZGv3XZfyDCzRATxg3+Ah IJiSRbgmfzMkyJ2kFx+I36Ed5LnFi3wVeq6lgXC0iyYStOZFUe2ZUXoVBwQkN22LXWST d2mpqVocUNV/GfwTVK020Rfz60aRa3KNYEpBxxvyA7q0WGamQEROVqFmX60H9fxubLnw lTbhJVIy8QQBvZmKSXThpQ1ax5xNvPN3i1IYcViqEZqVzaldjVfUnRbEJYjg0UmprTm4 0Vng== X-Forwarded-Encrypted: i=1; AKwUvBxUdYylqOS877X6UePlr67tBUYFg2fHsZJTrSygQXik51WMKekMoka+p23g4pIQ1Ghpz8HhZ+WYl3TYEx8=@vger.kernel.org X-Gm-Message-State: AFq9FYLGDBfKjs+GnFfQKJbUV6wUQ8qRDhYa6j0IzhiDxfLWAGlK1Ch9 8EGYBMegx2/DmZPuBdZeoFbcpVtnaennM/PTUnivbZlZFUE1q2oSOK+S X-Gm-Gg: AYBFou3CXX2tiv1ToAAJ4mSB4qvQz+91zLMOnemURqm2sqctikf8P5jupUkQ+vBDNu5 FSLvPC+oGqVfEPkQjyQC5thWWf6u9/KAh/WwTZ1MbMoD55rcurd9sO4uY0AhsPgqqOtTdWu5XE+ X+rDTT82Nt+DhN9Pm+L1Zi6bxXdt+h0SYwY/QZ8JyITOlcq2s3hwMbpogTnDG363FkduSry/gT3 UHP/jYG8aFA3o/auxcY3ST5Pof0k+Ep0zGJOznHqM7/f9VWwb/3dZqDBLUJmUojbgVytSp9ha9C aQpTsSqChikZtwneHvFZ0p005mg8xNnxLeS60cxK49K+fgP6yXY3woT83aAqTobZVQmYxR2qGTD O03mslzHct0yvVfgH98wEvcnJuWR3bD5gmeEuUZQDrd5GObKzFtT4uvgGnsTqudyTzHSwj/XMup DM+hIgm1UhNdTQgy8f/drwH+ww9uxjI8JOuQjrkQ58MGAvHAKJMJMZrOZcq/4xiXDxbR8c+bAOX R1SvTu+5xnHuXYSehG86XySX3sTUe1UCcKkLB+t6jbuLgeV59CBIAYxqOo0be5I63M= X-Received: by 2002:a05:6000:46db:b0:48b:e50:7152 with SMTP id ffacd0b85a97d-48dbaae21dcmr3251605f8f.28.1791563188334; Fri, 09 Oct 2026 09:26:28 -0700 (PDT) Received: from Raghu007.. (sgyl-44-b2-v4wan-174108-cust110.vm6.cable.virginm.net. [80.1.81.111]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-48db9abdaa5sm4745750f8f.35.2026.10.09.09.26.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 Oct 2026 09:26:27 -0700 (PDT) From: Palla Raghunath To: Pablo Neira Ayuso , Florian Westphal , Phil Sutter Cc: Fernando Fernandez Mancera , Karl Mehltretter , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Jesper Dangaard Brouer , netfilter-devel@vger.kernel.org, coreteam@netfilter.org, netdev@vger.kernel.org, Shuah Khan , Brigham Campbell , linux-kernel@vger.kernel.org, linux-kernel-mentees@lists.linux.dev, raghunathpalla.0209@gmail.com, syzbot+5a8667f002726fc59f88@syzkaller.appspotmail.com Subject: [PATCH nf v2] netfilter: synproxy: check TCP header before verifying checksum Date: Fri, 9 Oct 2026 17:26:24 +0100 Message-Id: <20261009162624.16294-1-raghunathpalla.0209@gmail.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit synproxy_tg6() calls nf_ip6_checksum() with par->thoff before it checks that there is actually a TCP header at that offset. par->thoff comes from ipv6_find_hdr(), which ip6_packet_match() calls with target -1. ipv6_find_hdr() only makes sure the first two bytes of each extension header are in the skb. It then adds the header's declared length to the offset and stops at the first non-extension header, so the offset it returns can be past the end of the packet. For a CHECKSUM_NONE skb, nf_ip6_checksum() then calls skb_checksum(skb, 0, thoff, 0), and if thoff is bigger than skb->len we hit the BUG_ON(len) in skb_checksum(): kernel BUG at net/core/skbuff.c:3606! RIP: 0010:skb_checksum+0x8b2/0x8c0 Call Trace: nf_ip6_checksum+0x1bd/0x320 net/netfilter/utils.c:89 synproxy_tg6+0x1a4/0x6e0 net/ipv6/netfilter/ip6t_SYNPROXY.c:21 ip6t_do_table+0xd37/0x15b0 net/ipv6/netfilter/ip6_tables.c:366 ... syzbot's reproducer sends a 60-byte packet with an AH header followed by two hop-by-hop headers. The second hop-by-hop header says the next header is TCP and has hdrlen 167, which gives a thoff of 1400. nft_synproxy_do_eval() has the same ordering: it calls nf_checksum() before it fetches the TCP header. In both places, get the TCP header with skb_header_pointer() first and only then verify the checksum, the same way nf_reject_ip6_tcphdr_get() does it. Packets that don't have a full TCP header at thoff are now dropped before we try to checksum them. Fixes: 4ad362282cb4 ("netfilter: add IPv6 SYNPROXY target") Fixes: a311a8981727 ("netfilter: nft_synproxy: use the family-aware checksum helper") Reported-by: syzbot+5a8667f002726fc59f88@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=5a8667f002726fc59f88 Reviewed-by: Fernando Fernandez Mancera Signed-off-by: Palla Raghunath --- Thanks Fernando for the review, and for spotting the nft_synproxy case and giving me the chance to fix it in this patch as well. v2: - Also fix nft_synproxy_do_eval() and add its Fixes: tag, as Fernando suggested - Drop the comment in synproxy_tg6() - Add Fernando's Reviewed-by - Rebase on v7.3-rc7 Testing: I ran syzbot's reproducer on v7.3-rc7 with this patch applied and ee319bd3a0e9 ("ipv6: do not let ipv6_find_hdr() return an offset past the packet end") reverted, since that commit already stops the bad offset from reaching the target on current trees. The BUG doesn't fire any more. The nft_synproxy change is only build-tested so far; I haven't managed to get a packet through an nft synproxy rule with the bad offset yet. v1: https://lore.kernel.org/all/20260926204519.43402-1-raghunathpalla.0209@gmail.com/ net/ipv6/netfilter/ip6t_SYNPROXY.c | 6 +++--- net/netfilter/nft_synproxy.c | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/net/ipv6/netfilter/ip6t_SYNPROXY.c b/net/ipv6/netfilter/ip6t_SYNPROXY.c index d51d0c3e5fe9..b3aa4fe67589 100644 --- a/net/ipv6/netfilter/ip6t_SYNPROXY.c +++ b/net/ipv6/netfilter/ip6t_SYNPROXY.c @@ -18,13 +18,13 @@ synproxy_tg6(struct sk_buff *skb, const struct xt_action_param *par) struct synproxy_options opts = {}; struct tcphdr *th, _th; - if (nf_ip6_checksum(skb, xt_hooknum(par), par->thoff, IPPROTO_TCP)) - return NF_DROP; - th = skb_header_pointer(skb, par->thoff, sizeof(_th), &_th); if (th == NULL) return NF_DROP; + if (nf_ip6_checksum(skb, xt_hooknum(par), par->thoff, IPPROTO_TCP)) + return NF_DROP; + if (!synproxy_parse_options(skb, par->thoff, th, &opts)) return NF_DROP; diff --git a/net/netfilter/nft_synproxy.c b/net/netfilter/nft_synproxy.c index 554a96a000f4..6b290a89886d 100644 --- a/net/netfilter/nft_synproxy.c +++ b/net/netfilter/nft_synproxy.c @@ -118,12 +118,6 @@ static void nft_synproxy_do_eval(const struct nft_synproxy *priv, return; } - if (nf_checksum(skb, nft_hook(pkt), thoff, IPPROTO_TCP, - nft_pf(pkt))) { - regs->verdict.code = NF_DROP; - return; - } - tcp = skb_header_pointer(skb, thoff, sizeof(struct tcphdr), &_tcph); @@ -132,6 +126,12 @@ static void nft_synproxy_do_eval(const struct nft_synproxy *priv, return; } + if (nf_checksum(skb, nft_hook(pkt), thoff, IPPROTO_TCP, + nft_pf(pkt))) { + regs->verdict.code = NF_DROP; + return; + } + if (!synproxy_parse_options(skb, thoff, tcp, &opts)) { regs->verdict.code = NF_DROP; return; -- 2.34.1