From: Eric Dumazet <edumazet@kernel.org>
To: "David S . Miller" <davem@davemloft.net>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>
Cc: Kuniyuki Iwashima <kuniyu@google.com>,
Neal Cardwell <ncardwell@google.com>,
Ido Schimmel <idosch@nvidia.com>,
Theodor Arsenij Larionov Trichkine <theodorlarionov@gmail.com>,
Simon Horman <horms@kernel.org>,
netdev@vger.kernel.org, Eric Dumazet <edumazet@kernel.org>
Subject: [PATCH v3 net 1/2] net: use the full socket in sk_mc_loop()
Date: Mon, 12 Oct 2026 12:10:28 +0200 [thread overview]
Message-ID: <20261012101029.927296-2-edumazet@kernel.org> (raw)
In-Reply-To: <20261012101029.927296-1-edumazet@kernel.org>
From: Theodor Arsenij Larionov Trichkine <theodorlarionov@gmail.com>
sk_mc_loop() is called from ip_mc_output() and ip6_finish_output2()
with skb->sk, which is not always a full socket:
- Since commit ca6fb0651883 ("tcp: attach SYNACK messages to request
sockets instead of listener"), a SYNACK is attached to its request
socket.
- Since commit 79636038d37e ("ipv4: tcp: give socket pointer to control
skbs"), an ACK or RST sent by ip_send_unicast_reply() on behalf of a
TIME_WAIT socket is attached to the timewait socket.
When such a packet uses a multicast route, inet_test_bit(MC_LOOP, sk)
reads inet_flags past the end of the request or timewait socket.
This happens for instance when a SYN with a multicast source address
reaches a listener, after being looped back with its dst attached, so
that ip_rcv_finish_core() skips the martian source check. A raw
IP_HDRINCL socket sending to a local address does this, as does
re-injection by nft dup or the iptables TEE target. The destination
can also come from a source route option, or from a route of type
multicast covering a unicast prefix.
BUG: KASAN: slab-out-of-bounds in sk_mc_loop+0x111/0x170
Read of size 8 at addr ffff88800f2b7f10 by task repro-raw/470
Call Trace:
<IRQ>
sk_mc_loop+0x111/0x170
ip_mc_output+0x355/0x930
ip_build_and_send_pkt+0xb87/0xc50
tcp_v4_send_synack+0x500/0x6f0
tcp_conn_request+0x2135/0x2d90
tcp_v4_conn_request+0xa5/0x210
tcp_rcv_state_process+0x136e/0x6920
tcp_v4_do_rcv+0x339/0xb10
tcp_v4_rcv+0x34ab/0x3ab0
ip_protocol_deliver_rcu+0x6e/0x3e0
ip_local_deliver_finish+0x34d/0x510
ip_local_deliver+0x1bc/0x310
ip_rcv+0x390/0x410
__netif_receive_skb_one_core+0x199/0x1e0
process_backlog+0x239/0x680
__napi_poll+0xb5/0x650
net_rx_action+0x980/0xd60
handle_softirqs+0x17f/0x590
do_softirq+0x3f/0x60
</IRQ>
The buggy address belongs to the object at ffff88800f2b7d60
which belongs to the cache request_sock_TCP of size 312
The buggy address is located 120 bytes to the right of
allocated 312-byte region [ffff88800f2b7d60, ffff88800f2b7e98)
Use sk_const_to_full_sk(), which restores the behavior from before
the two commits above: a request socket uses the setting of its
listener, and a timewait socket gets the default (loop back), as the
per-cpu control socket used before had.
Fixes: ca6fb0651883 ("tcp: attach SYNACK messages to request sockets instead of listener")
Fixes: 79636038d37e ("ipv4: tcp: give socket pointer to control skbs")
Signed-off-by: Theodor Arsenij Larionov Trichkine <theodorlarionov@gmail.com>
[edumazet: rewrote the changelog, added the TIME_WAIT case]
Signed-off-by: Eric Dumazet <edumazet@kernel.org>
---
v3:
- Back to the v1 approach: checking the destination in TCP (v2) does
not cover source routes, multicast typed routes on unicast prefixes,
or the TIME_WAIT reply path (sashiko).
- Add the TIME_WAIT case and its Fixes tag.
v2: https://lore.kernel.org/netdev/20261008114942.1376889-1-theodorlarionov@gmail.com/
v1: https://lore.kernel.org/netdev/20261008100423.1256884-1-theodorlarionov@gmail.com/
net/core/sock.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/core/sock.c b/net/core/sock.c
index e8551df8330ff4b1d662b0d0133e20d1f74eb728..1302c1e848b2a3c40e86ff37af9c20c1a9f4662a 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -769,6 +769,7 @@ bool sk_mc_loop(const struct sock *sk)
{
if (dev_recursion_level())
return false;
+ sk = sk_const_to_full_sk(sk);
if (!sk)
return true;
/* IPV6_ADDRFORM can change sk->sk_family under us. */
--
2.53.0
next prev parent reply other threads:[~2026-10-12 10:10 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-12 10:10 [PATCH v3 net 0/2] net: fix sk_mc_loop() with request and timewait sockets Eric Dumazet
2026-10-12 10:10 ` Eric Dumazet [this message]
2026-10-13 1:09 ` [PATCH v3 net 1/2] net: use the full socket in sk_mc_loop() Kuniyuki Iwashima
2026-10-12 10:10 ` [PATCH v3 net 2/2] tcp: use the echoed source route in cookie_v4_check() Eric Dumazet
2026-10-13 1:25 ` Kuniyuki Iwashima
2026-10-12 10:14 ` [PATCH v3 net 0/2] net: fix sk_mc_loop() with request and timewait sockets netdev-bot+sinfo
2026-10-16 1:40 ` patchwork-bot+netdevbpf
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=20261012101029.927296-2-edumazet@kernel.org \
--to=edumazet@kernel.org \
--cc=davem@davemloft.net \
--cc=horms@kernel.org \
--cc=idosch@nvidia.com \
--cc=kuba@kernel.org \
--cc=kuniyu@google.com \
--cc=ncardwell@google.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=theodorlarionov@gmail.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.