From: sashiko-bot@kernel.org
To: "Jiayuan Chen" <jiayuan.chen@linux.dev>
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH bpf-next v3 5/7] sockmap: Fix use-after-free in udp_bpf_recvmsg()
Date: Fri, 12 Jun 2026 13:24:54 +0000 [thread overview]
Message-ID: <20260612132454.F14321F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260612130919.299124-6-jiayuan.chen@linux.dev>
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
New issues:
- [Critical] Infinite loop holding the socket lock when data is pending in `ingress_skb` but not yet in `ingress_msg`.
Pre-existing issues:
- [High] Blocking recvmsg() incorrectly returns -EAGAIN instead of -EINTR (-ERESTARTSYS) when interrupted by a signal.
- [High] Delegating to `sk_udp_recvmsg` ignores data subsequently arriving via BPF redirect, causing a permanent hang.
- [High] udp_bpf_recvmsg() resets the receive timeout on every loop iteration, allowing indefinite blocking despite SO_RCVTIMEO.
- [High] udp_msg_wait_data() does not check sk_shutdown after waking up, causing recvmsg to return -EAGAIN instead of 0 on a closed socket.
--
commit d3eae210a4563564468c062b23ec1d89b4e36196
Author: Kuniyuki Iwashima <kuniyu@google.com>
sockmap: Fix use-after-free in udp_bpf_recvmsg()
This commit fixes a use-after-free of struct sk_msg in sk_msg_recvmsg()
reported by syzbot. It serialises sk_msg_recvmsg() by adding lock_sock()
inside udp_bpf_recvmsg(), ensuring that multiple threads do not concurrently
process the same sk_msg.
Link: https://lore.kernel.org/netdev/69922ac9.a70a0220.2c38d7.00e0.GAE@google.com/
> diff --git a/net/ipv4/udp_bpf.c b/net/ipv4/udp_bpf.c
> index 9f33b07b14813..ad57c4c9eaab6 100644
> --- a/net/ipv4/udp_bpf.c
> +++ b/net/ipv4/udp_bpf.c
> @@ -50,7 +50,9 @@ static int udp_msg_wait_data(struct sock *sk, struct sk_psock *psock,
> sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
> ret = udp_msg_has_data(sk, psock);
> if (!ret) {
> + release_sock(sk);
> wait_woken(&wait, TASK_INTERRUPTIBLE, timeo);
> + lock_sock(sk);
> ret = udp_msg_has_data(sk, psock);
[Severity: High]
This is a pre-existing issue, but does this miss checking for socket shutdown
after waking up?
If the socket is shut down (RCV_SHUTDOWN) while the thread is sleeping in
wait_woken(), the thread wakes up and evaluates udp_msg_has_data(). If it
finds no data, it returns 0.
The caller udp_bpf_recvmsg() then sets copied = -EAGAIN and returns it to
userspace. Does this violate POSIX semantics, which require a blocking
recvmsg() to return 0 (EOF) immediately on a gracefully closed socket?
[Severity: High]
This is also a pre-existing issue, but is there a missing check for
signal_pending(current) here?
If wait_woken() is interrupted by a signal, it returns early. Since
udp_msg_wait_data() fails to check for signals after the wait, it will
return 0 if no data has arrived.
In udp_bpf_recvmsg(), this 0 is unconditionally translated to -EAGAIN.
Should this instead return -EINTR / -ERESTARTSYS when interrupted by a
signal? Returning -EAGAIN on a blocking socket can cause applications
to fail or spin indefinitely.
> }
> sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
[ ... ]
> if (!psock_has_data(psock)) {
> ret = sk_udp_recvmsg(sk, msg, len, flags);
> goto out;
> }
[Severity: High]
This is a pre-existing issue, but does delegating to sk_udp_recvmsg() here
ignore data that might arrive via BPF redirect?
If the socket currently has no data (!psock_has_data(psock)), the fast path
drops into sk_udp_recvmsg(). If the socket is blocking, sk_udp_recvmsg()
will block waiting for data in sk->sk_receive_queue.
If a BPF program subsequently redirects a packet to this socket's psock, the
wait queue is woken up, but sk_udp_recvmsg() only checks
sk->sk_receive_queue. Finding it empty, it will go back to sleep
indefinitely. Can this result in a permanent hang?
>
> + lock_sock(sk);
> msg_bytes_ready:
> copied = sk_msg_recvmsg(sk, psock, msg, len, flags);
> if (!copied) {
> long timeo;
> int data;
>
> timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
[Severity: High]
This is a pre-existing issue, but does this reset the receive timeout on
every loop iteration?
Inside the loop, sock_rcvtimeo() is called to fetch the timeout value.
udp_msg_wait_data() uses this timeout, but drops the remaining time when it
returns.
On the next iteration (for example, due to a spurious wakeup),
sock_rcvtimeo() is called again, reloading the full original timeout from
the socket. Doesn't this break SO_RCVTIMEO semantics by allowing the socket
to block indefinitely if wakeups keep occurring?
> data = udp_msg_wait_data(sk, psock, timeo);
> if (data) {
> if (psock_has_data(psock))
> goto msg_bytes_ready;
[Severity: Critical]
Does this loop introduce a hard lockup if data is pending in the
ingress_skb queue but not yet in ingress_msg?
If data is queued in psock->ingress_skb but not yet processed into
psock->ingress_msg, psock_has_data() returns true, but sk_msg_recvmsg()
returns 0.
The code then calls udp_msg_wait_data():
static int udp_msg_wait_data(...)
{
...
ret = udp_msg_has_data(sk, psock);
if (!ret) {
release_sock(sk);
wait_woken(&wait, TASK_INTERRUPTIBLE, timeo);
lock_sock(sk);
...
}
return ret;
}
Because udp_msg_has_data() evaluates to true, udp_msg_wait_data() returns 1
immediately WITHOUT releasing lock_sock(sk).
Back in udp_bpf_recvmsg(), the code sees data is non-zero and
psock_has_data() is true, so it jumps to msg_bytes_ready. Because we still
hold lock_sock(sk), no other thread can process the ingress_skb, and
sk_msg_recvmsg() will again return 0.
Can this result in a 100% CPU tight spin loop while holding the socket
lock?
> +
> + release_sock(sk);
> +
> ret = sk_udp_recvmsg(sk, msg, len, flags);
> goto out;
> }
> copied = -EAGAIN;
> }
> +
> + release_sock(sk);
> +
> ret = copied;
> out:
> sk_psock_put(sk, psock);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260612130919.299124-1-jiayuan.chen@linux.dev?part=5
next prev parent reply other threads:[~2026-06-12 13:24 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-12 13:07 [PATCH bpf-next v3 0/7] bpf, skmsg: some fixes for skmsg Jiayuan Chen
2026-06-12 13:07 ` [PATCH bpf-next v3 1/7] bpf, sockmap: reject overflowing copy + len in bpf_msg_push_data() Jiayuan Chen
2026-06-12 13:28 ` sashiko-bot
2026-06-13 0:09 ` Kuniyuki Iwashima
2026-06-12 13:07 ` [PATCH bpf-next v3 2/7] bpf, sockmap: Fix wrong rsge offset " Jiayuan Chen
2026-06-12 13:27 ` sashiko-bot
2026-06-13 0:17 ` Kuniyuki Iwashima
2026-06-12 13:07 ` [PATCH bpf-next v3 3/7] bpf, sockmap: zero-initialize pages allocated in bpf_msg_push_data Jiayuan Chen
2026-06-12 13:34 ` sashiko-bot
2026-06-13 0:28 ` Kuniyuki Iwashima
2026-06-13 1:36 ` Alexei Starovoitov
2026-06-12 13:07 ` [PATCH bpf-next v3 4/7] bpf, sockmap: keep sk_msg copy state in sync Jiayuan Chen
2026-06-12 13:57 ` bot+bpf-ci
2026-06-13 0:40 ` Kuniyuki Iwashima
2026-06-12 13:07 ` [PATCH bpf-next v3 5/7] sockmap: Fix use-after-free in udp_bpf_recvmsg() Jiayuan Chen
2026-06-12 13:24 ` sashiko-bot [this message]
2026-06-12 13:07 ` [PATCH bpf-next v3 6/7] bpf, sockmap: fix integer overflow in bpf_msg_pop_data() bounds check Jiayuan Chen
2026-06-13 0:44 ` Kuniyuki Iwashima
2026-06-12 13:07 ` [PATCH bpf-next v3 7/7] selftests/bpf: add test for bpf_msg_pop_data() overflow Jiayuan Chen
2026-06-12 17:09 ` [PATCH bpf-next v3 0/7] bpf, skmsg: some fixes for skmsg Alexei Starovoitov
2026-06-12 18:43 ` Kuniyuki Iwashima
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=20260612132454.F14321F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=jiayuan.chen@linux.dev \
--cc=sashiko-reviews@lists.linux.dev \
/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