From: Daehyeon Ko <4ncienth@gmail.com>
To: netdev@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH net] udp: revalidate socket family before publishing an IPv6 cork
Date: Wed, 26 Aug 2026 01:06:30 +0900 [thread overview]
Message-ID: <20260825160630.1888866-1-4ncienth@gmail.com> (raw)
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
next reply other threads:[~2026-08-25 16:06 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-25 16:06 Daehyeon Ko [this message]
2026-08-28 23:02 ` Jakub Kicinski
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=20260825160630.1888866-1-4ncienth@gmail.com \
--to=4ncienth@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
/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
all inboxes | Powered by JetHome®