In 'udp_bpf_recvmsg()', 'sk_msg_recvmsg()' should be called
with socket locked. Otherwise two threads may peek the same
message, and one of the threads may dequeue and free that
message while it is still processed by another thread.
Reported-by: syzbot+431f9a9e3f5227fbb904@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=431f9a9e3f5227fbb904
Fixes: 1f5be6b3b063 ("udp: Implement udp_bpf_recvmsg() for sockmap")
Signed-off-by: Dmitry Antipov <redacted>
---
net/ipv4/udp_bpf.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/udp_bpf.c b/net/ipv4/udp_bpf.c
index 9f33b07b1481..ac628eaa7759 100644
--- a/net/ipv4/udp_bpf.c
+++ b/net/ipv4/udp_bpf.c
@@ -79,6 +79,7 @@ static int udp_bpf_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
goto out;
}
+ lock_sock(sk);
msg_bytes_ready:
copied = sk_msg_recvmsg(sk, psock, msg, len, flags);
if (!copied) {@@ -91,11 +92,13 @@ static int udp_bpf_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
if (psock_has_data(psock))
goto msg_bytes_ready;
ret = sk_udp_recvmsg(sk, msg, len, flags);
- goto out;
+ goto unlock;
}
copied = -EAGAIN;
}
ret = copied;
+unlock:
+ release_sock(sk);
out:
sk_psock_put(sk, psock);
return ret;
--
2.54.0