mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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


             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®