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@kernel.org, horms@kernel.org,
fw@strlen.de, ja@ssi.bg
Subject: [PATCH net-next 09/15] ipvs: fix buffer overflow when sending sync messages
Date: Sun, 11 Oct 2026 23:59:47 +0200 [thread overview]
Message-ID: <20261011215953.1334630-10-pablo@netfilter.org> (raw)
In-Reply-To: <20261011215953.1334630-1-pablo@netfilter.org>
From: Julian Anastasov <ja@ssi.bg>
Sashiko reports for possible heap buffer overflow when
generating sync message for the v0 and v1 message formats.
We should read the cp->flags only once because another
CPU can concurrently set the SEQ_MASK between the two
reads.
Note that IPVS does not set the SEQ_MASK anymore for the
ip_vs_ftp.c helper starting from commit 7f1c40757951
("IPVS: make FTP work with full NAT support") (2.6.36+),
so the problem should not be reproducible.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Link: https://sashiko.dev/#/patchset/20260903004149.1037028-1-pablo%40netfilter.org
Link: https://sashiko.dev/#/patchset/20260909111338.44357-1-ja%40ssi.bg
Signed-off-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/ipvs/ip_vs_sync.c | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index 45655cff078c..157f5c8361ab 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -543,13 +543,15 @@ static void ip_vs_sync_conn_v0(struct netns_ipvs *ipvs, struct ip_vs_conn *cp,
struct ip_vs_sync_conn_v0 *s;
struct ip_vs_sync_buff *buff;
struct ipvs_master_sync_state *ms;
- int id;
+ u32 flags, seq_mask;
unsigned int len;
+ int id;
if (unlikely(cp->af != AF_INET))
return;
+ flags = READ_ONCE(cp->flags);
/* Do not sync ONE PACKET */
- if (cp->flags & IP_VS_CONN_F_ONE_PACKET)
+ if (flags & IP_VS_CONN_F_ONE_PACKET)
return;
if (!ip_vs_sync_conn_needed(ipvs, cp, pkts))
@@ -564,8 +566,8 @@ static void ip_vs_sync_conn_v0(struct netns_ipvs *ipvs, struct ip_vs_conn *cp,
id = select_master_thread_id(ipvs, cp);
ms = &ipvs->ms[id];
buff = ms->sync_buff;
- len = (cp->flags & IP_VS_CONN_F_SEQ_MASK) ? FULL_CONN_SIZE :
- SIMPLE_CONN_SIZE;
+ seq_mask = flags & IP_VS_CONN_F_SEQ_MASK;
+ len = seq_mask ? FULL_CONN_SIZE : SIMPLE_CONN_SIZE;
if (buff) {
m = (struct ip_vs_sync_mesg_v0 *) buff->mesg;
/* Send buffer if it is for v1 */
@@ -597,9 +599,9 @@ static void ip_vs_sync_conn_v0(struct netns_ipvs *ipvs, struct ip_vs_conn *cp,
s->caddr = cp->caddr.ip;
s->vaddr = cp->vaddr.ip;
s->daddr = cp->daddr.ip;
- s->flags = htons(cp->flags & ~IP_VS_CONN_F_HASHED);
+ s->flags = htons(flags & ~IP_VS_CONN_F_HASHED);
s->state = htons(cp->state);
- if (cp->flags & IP_VS_CONN_F_SEQ_MASK) {
+ if (seq_mask) {
struct ip_vs_sync_conn_options *opt =
(struct ip_vs_sync_conn_options *)&s[1];
memcpy(opt, &cp->sync_conn_opt, sizeof(*opt));
@@ -635,6 +637,7 @@ void ip_vs_sync_conn(struct netns_ipvs *ipvs, struct ip_vs_conn *cp, int pkts)
int id;
__u8 *p;
unsigned int len, pe_name_len, pad;
+ u32 flags, seq_mask;
/* Handle old version of the protocol */
if (sysctl_sync_ver(ipvs) == 0) {
@@ -647,6 +650,7 @@ void ip_vs_sync_conn(struct netns_ipvs *ipvs, struct ip_vs_conn *cp, int pkts)
sloop:
if (!ip_vs_sync_conn_needed(ipvs, cp, pkts))
goto control;
+ flags = READ_ONCE(cp->flags);
/* Sanity checks */
pe_name_len = 0;
@@ -674,7 +678,8 @@ void ip_vs_sync_conn(struct netns_ipvs *ipvs, struct ip_vs_conn *cp, int pkts)
#endif
len = sizeof(struct ip_vs_sync_v4);
- if (cp->flags & IP_VS_CONN_F_SEQ_MASK)
+ seq_mask = flags & IP_VS_CONN_F_SEQ_MASK;
+ if (seq_mask)
len += sizeof(struct ip_vs_sync_conn_options) + 2;
if (cp->pe_data_len)
@@ -720,7 +725,7 @@ void ip_vs_sync_conn(struct netns_ipvs *ipvs, struct ip_vs_conn *cp, int pkts)
/* Set message type & copy members */
s->v4.type = (cp->af == AF_INET6 ? STYPE_F_INET6 : 0);
s->v4.ver_size = htons(len & SVER_MASK); /* Version 0 */
- s->v4.flags = htonl(cp->flags & ~IP_VS_CONN_F_HASHED);
+ s->v4.flags = htonl(flags & ~IP_VS_CONN_F_HASHED);
s->v4.state = htons(cp->state);
s->v4.protocol = cp->protocol;
s->v4.cport = cp->cport;
@@ -744,7 +749,7 @@ void ip_vs_sync_conn(struct netns_ipvs *ipvs, struct ip_vs_conn *cp, int pkts)
s->v4.vaddr = cp->vaddr.ip;
s->v4.daddr = cp->daddr.ip;
}
- if (cp->flags & IP_VS_CONN_F_SEQ_MASK) {
+ if (seq_mask) {
*(p++) = IPVS_OPT_SEQ_DATA;
*(p++) = sizeof(struct ip_vs_sync_conn_options);
hton_seq(&cp->in_seq, (struct ip_vs_seq *)p);
--
2.47.3
next prev parent reply other threads:[~2026-10-11 22:00 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-11 21:59 [PATCH net-next 00/15] Netfilter/IPVS updates for net-next Pablo Neira Ayuso
2026-10-11 21:59 ` [PATCH net-next 01/15] netfilter: disable br_netfilter in user namespaces Pablo Neira Ayuso
2026-10-11 21:59 ` [PATCH net-next 02/15] netfilter: flowtable: recognize IPv4/IPv6 in tunnel proto matching Pablo Neira Ayuso
2026-10-11 21:59 ` [PATCH net-next 03/15] netfilter: flowtable: set inner protocol when popping tunnel header Pablo Neira Ayuso
2026-10-11 21:59 ` [PATCH net-next 04/15] netfilter: flowtable: populate tunnel tuple regardless of inner protocol Pablo Neira Ayuso
2026-10-11 21:59 ` [PATCH net-next 05/15] netfilter: flowtable: add encap_proto to flow_offload_tunnel Pablo Neira Ayuso
2026-10-11 21:59 ` [PATCH net-next 06/15] netfilter: flowtable: refactor MTU check for tunnel offload Pablo Neira Ayuso
2026-10-11 21:59 ` [PATCH net-next 07/15] netfilter: flowtable: unify tunnel push for IPv4 and IPv6 Pablo Neira Ayuso
2026-10-11 21:59 ` [PATCH net-next 08/15] selftests: netfilter: nft_queue.sh: only queue icmp echo request/reply Pablo Neira Ayuso
2026-10-11 21:59 ` Pablo Neira Ayuso [this message]
2026-10-11 21:59 ` [PATCH net-next 10/15] netfilter: conntrack: fix unlikely UaF in gc worker Pablo Neira Ayuso
2026-10-11 21:59 ` [PATCH net-next 11/15] netfilter: nf_tables: switch chain_types array to rcu Pablo Neira Ayuso
2026-10-11 21:59 ` [PATCH net-next 12/15] netfilter: add nf_skb_sk helper and use it Pablo Neira Ayuso
2026-10-11 21:59 ` [PATCH net-next 13/15] netfilter: add nf_sk_to_full_sk " Pablo Neira Ayuso
2026-10-11 21:59 ` [PATCH net-next 14/15] netfilter: nft_exthdr: remove redundant op parsing in tcp_set_init Pablo Neira Ayuso
2026-10-11 21:59 ` [PATCH net-next 15/15] netfilter: nft_exthdr: avoid 60 bytes stack buffer in TCP option mangling 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=20261011215953.1334630-10-pablo@netfilter.org \
--to=pablo@netfilter.org \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--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