* [PATCH net] udp: revalidate socket family before publishing an IPv6 cork
@ 2026-08-25 16:06 Daehyeon Ko
0 siblings, 0 replies; only message in thread
From: Daehyeon Ko @ 2026-08-25 16:06 UTC (permalink / raw)
To: netdev; +Cc: linux-kernel
udpv6_sendmsg() prepares the IPv6 flow and route before taking the socket
lock when a datagram is corked. IPV6_ADDRFORM takes the same lock, but it
can convert the socket to AF_INET while the send path is doing that
lockless preparation because no cork has been published yet.
If the conversion wins the race, udpv6_sendmsg() later publishes an
AF_INET6 cork on an AF_INET socket. Uncorking through the IPv4 socket
operations then interprets the IPv6 cork as IPv4 state. The IPv4
finalizer writes a 20-byte IPv4 header into the 40-byte IPv6 header
reservation while the retained IPv6 dst routes the skb through
ip6_output(). ip6_finish_output2() consequently consumes the unwritten
20-byte tail.
An unprivileged reproducer triggered the mixed state on 12 of 10,000
sockets. KMSAN reported an uninitialized-value read in
ip6_finish_output2() on three fresh boots, with the allocation origin in
__alloc_skb() through __ip6_append_data(). The same process recovered the
20-byte region from the TX timestamp error queue; one of three fresh boots
contained recognizable stale heap data.
After taking the lock, revalidate that IPV6_ADDRFORM has not changed the
socket family before publishing the cork. The existing error path releases
the prepared dst, flowlabel, and transmit-option references. With this
change, the serialized controls retain their existing results and the
forbidden mixed state occurred zero times across 20,000 sockets.
Fixes: 03485f2adcde ("udpv6: Add lockless sendmsg() support")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
---
net/ipv6/udp.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index fd875908ac0c66..566c634a5a5945 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1716,6 +1716,11 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
}
lock_sock(sk);
+ if (unlikely(sk->sk_family != AF_INET6)) {
+ release_sock(sk);
+ err = -EAFNOSUPPORT;
+ goto out;
+ }
if (unlikely(up->pending)) {
/* The socket is already corked while preparing it. */
/* ... which is an evident application bug. --ANK */
--
2.54.0
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-08-25 16:06 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-25 16:06 [PATCH net] udp: revalidate socket family before publishing an IPv6 cork Daehyeon Ko
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.