From 88b84cae6b94087d3a9679845fe28ad19c7bef8b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 7 Sep 2026 07:58:40 +0000 Subject: [PATCH] ip_tunnel: use WRITE_ONCE in ip_tunnel_encap_setup Update ip_tunnel_encap_setup() to use WRITE_ONCE() when writing to encap fields (type, sport, dport, flags) and hlen fields. This ensures that concurrent lockless readers (like fill_info) do not see torn writes. Also remove the unsafe memset() on t->encap which could cause concurrent readers to transiently see zeroed fields. Removing it also fixes a bug where t->encap was left cleared even if ip_encap_hlen() failed, resulting in partial configuration. Fixes: 56328486539d ("net: Changes to ip_tunnel to support foo-over-udp encapsulation") Signed-off-by: Eric Dumazet Acked-by: Lorenzo Bianconi Link: https://patch.msgid.link/20260907075846.2913645-4-edumazet@google.com Signed-off-by: Jakub Kicinski --- net/ipv4/ip_tunnel.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index e6bcf01411d0..13b5e35e8790 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -491,19 +491,17 @@ int ip_tunnel_encap_setup(struct ip_tunnel *t, { int hlen; - memset(&t->encap, 0, sizeof(t->encap)); - hlen = ip_encap_hlen(ipencap); if (hlen < 0) return hlen; - t->encap.type = ipencap->type; - t->encap.sport = ipencap->sport; - t->encap.dport = ipencap->dport; - t->encap.flags = ipencap->flags; + WRITE_ONCE(t->encap.type, ipencap->type); + WRITE_ONCE(t->encap.sport, ipencap->sport); + WRITE_ONCE(t->encap.dport, ipencap->dport); + WRITE_ONCE(t->encap.flags, ipencap->flags); - t->encap_hlen = hlen; - t->hlen = t->encap_hlen + t->tun_hlen; + WRITE_ONCE(t->encap_hlen, hlen); + WRITE_ONCE(t->hlen, hlen + t->tun_hlen); return 0; }