From: Pablo Neira Ayuso <pablo@netfilter.org>
To: netfilter-devel@vger.kernel.org
Cc: davem@davemloft.net, netdev@vger.kernel.org, kuba@kernel.org,
pabeni@redhat.com, edumazet@google.com, horms@kernel.org,
fw@strlen.de, ja@ssi.bg
Subject: [PATCH net 09/13] ipvs: revalidate ihl to prevent out-of-bounds access
Date: Mon, 10 Aug 2026 21:06:17 +0200 [thread overview]
Message-ID: <20260810190621.894119-10-pablo@netfilter.org> (raw)
In-Reply-To: <20260810190621.894119-1-pablo@netfilter.org>
From: Julian Anastasov <ja@ssi.bg>
While the outer IP header is already pulled into the skb head,
we must be careful and revalidate the embedded headers after
reading them from the skb frags to prevent out-of-bounds
access.
One such place reported by Sashiko is ip_vs_nat_icmp() where
local process can change the ihl field and after
skb_ensure_writable() we can see larger value which is a
problem for the ip_send_check(cih) calls.
Add check to drop the packet if the ihl field is changed.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Link: https://sashiko.dev/#/patchset/20260730183506.87473-1-ja%40ssi.bg
Signed-off-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/ip_vs.h | 2 +-
net/netfilter/ipvs/ip_vs_core.c | 11 +++++++++--
net/netfilter/ipvs/ip_vs_xmit.c | 3 ++-
3 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index fc2ef5ef31a6..be3a6617adf4 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -2068,7 +2068,7 @@ static inline bool ip_vs_conn_use_hash2(struct ip_vs_conn *cp)
!(cp->flags & IP_VS_CONN_F_TEMPLATE);
}
-void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,
+bool ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,
struct ip_vs_conn *cp, int dir, unsigned int toff,
bool has_ports, struct ip_vs_iphdr *ciph);
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index a46e7acdd8e1..eb806813292a 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -923,7 +923,7 @@ static int ip_vs_route_me_harder(struct netns_ipvs *ipvs, int af,
* Packet has been made sufficiently writable in caller
* - inout: 1=in->out, 0=out->in
*/
-void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,
+bool ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,
struct ip_vs_conn *cp, int inout, unsigned int toff,
bool has_ports, struct ip_vs_iphdr *ciph)
{
@@ -931,6 +931,11 @@ void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,
struct icmphdr *icmph = (struct icmphdr *)(skb->data + toff);
struct iphdr *cih = (struct iphdr *)(icmph + 1);
+ /* Before now we may used ihl from skb frag, revalidate it after
+ * copying it into skb head to prevent out-of-bounds access
+ */
+ if (cih->ihl * 4 != ciph->len - ciph->off)
+ return false;
if (inout) {
iph->saddr = cp->vaddr.ip;
ip_send_check(iph);
@@ -964,6 +969,7 @@ void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,
else
IP_VS_DBG_PKT(11, AF_INET, pp, skb, ciph->off,
"Forwarding altered incoming ICMP");
+ return true;
}
#ifdef CONFIG_IP_VS_IPV6
@@ -1055,7 +1061,8 @@ static int handle_response_icmp(int af, struct sk_buff *skb,
ip_vs_nat_icmp_v6(skb, pp, cp, 1, toff, has_ports, ciph);
else
#endif
- ip_vs_nat_icmp(skb, pp, cp, 1, toff, has_ports, ciph);
+ if (!ip_vs_nat_icmp(skb, pp, cp, 1, toff, has_ports, ciph))
+ goto out;
if (ip_vs_route_me_harder(cp->ipvs, af, skb, hooknum))
goto out;
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index fc7403186394..04450a48f01a 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -1580,7 +1580,8 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
if (skb_cow(skb, rt->dst.dev->hard_header_len))
goto tx_error;
- ip_vs_nat_icmp(skb, pp, cp, 0, toff, has_ports, ciph);
+ if (!ip_vs_nat_icmp(skb, pp, cp, 0, toff, has_ports, ciph))
+ goto tx_error;
/* Another hack: avoid icmp_send in ip_fragment */
skb->ignore_df = 1;
--
2.47.3
next prev parent reply other threads:[~2026-08-10 19:06 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-10 19:06 [PATCH net 00/13] Netfilter/IPVS fixes for net Pablo Neira Ayuso
2026-08-10 19:06 ` [PATCH net 01/13] netfilter: ipset: fix refcount race between list:set GC and swap Pablo Neira Ayuso
2026-08-10 19:06 ` [PATCH net 02/13] netfilter: bridge: release template ct on non-IP path Pablo Neira Ayuso
2026-08-10 19:06 ` [PATCH net 03/13] ipvs: add totalconns for dest Pablo Neira Ayuso
2026-08-10 19:06 ` [PATCH net 04/13] ipvs: properly update the overload flag on dest edit Pablo Neira Ayuso
2026-08-10 19:06 ` [PATCH net 05/13] ipvs: separate destination availability state Pablo Neira Ayuso
2026-08-10 19:06 ` [PATCH net 06/13] netfilter: nf_conntrack: defer invalid log until after unlock Pablo Neira Ayuso
2026-08-10 19:06 ` [PATCH net 07/13] netfilter: nfnetlink_log: wait for rcu grace period before freeing pernet state Pablo Neira Ayuso
2026-08-10 19:06 ` [PATCH net 08/13] ipvs: clear IPv4 options after rebasing tunnel ICMP errors Pablo Neira Ayuso
2026-08-10 19:06 ` Pablo Neira Ayuso [this message]
2026-08-10 19:06 ` [PATCH net 10/13] netfilter: nf_tables_offload: suppress WARN_ON_ONCE for ENOMEM in abort path Pablo Neira Ayuso
2026-08-10 19:06 ` [PATCH net 11/13] netfilter: flowtable: publish GC-visible tuple last Pablo Neira Ayuso
2026-08-10 19:06 ` [PATCH net 12/13] netfilter: ipset: fix list type element drift bug Pablo Neira Ayuso
2026-08-10 19:06 ` [PATCH net 13/13] netfilter: ipset: let destroy callbacks adjust ext mem size Pablo Neira Ayuso
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=20260810190621.894119-10-pablo@netfilter.org \
--to=pablo@netfilter.org \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=fw@strlen.de \
--cc=horms@kernel.org \
--cc=ja@ssi.bg \
--cc=kuba@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=netfilter-devel@vger.kernel.org \
--cc=pabeni@redhat.com \
/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