Skip to content

Commit 69139d2

Browse files
Cong WangPaolo Abeni
authored andcommitted
vsock: fix recursive ->recvmsg calls
After a vsock socket has been added to a BPF sockmap, its prot->recvmsg has been replaced with vsock_bpf_recvmsg(). Thus the following recursiion could happen: vsock_bpf_recvmsg() -> __vsock_recvmsg() -> vsock_connectible_recvmsg() -> prot->recvmsg() -> vsock_bpf_recvmsg() again We need to fix it by calling the original ->recvmsg() without any BPF sockmap logic in __vsock_recvmsg(). Fixes: 634f1a7 ("vsock: support sockmap") Reported-by: [email protected] Tested-by: [email protected] Cc: Bobby Eshleman <[email protected]> Cc: Michael S. Tsirkin <[email protected]> Cc: Stefano Garzarella <[email protected]> Signed-off-by: Cong Wang <[email protected]> Acked-by: Michael S. Tsirkin <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
1 parent b2ca166 commit 69139d2

File tree

3 files changed

+35
-23
lines changed

3 files changed

+35
-23
lines changed

include/net/af_vsock.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,12 @@ struct vsock_tap {
230230
int vsock_add_tap(struct vsock_tap *vt);
231231
int vsock_remove_tap(struct vsock_tap *vt);
232232
void vsock_deliver_tap(struct sk_buff *build_skb(void *opaque), void *opaque);
233+
int __vsock_connectible_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
234+
int flags);
233235
int vsock_connectible_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
234236
int flags);
237+
int __vsock_dgram_recvmsg(struct socket *sock, struct msghdr *msg,
238+
size_t len, int flags);
235239
int vsock_dgram_recvmsg(struct socket *sock, struct msghdr *msg,
236240
size_t len, int flags);
237241

net/vmw_vsock/af_vsock.c

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1270,25 +1270,28 @@ static int vsock_dgram_connect(struct socket *sock,
12701270
return err;
12711271
}
12721272

1273+
int __vsock_dgram_recvmsg(struct socket *sock, struct msghdr *msg,
1274+
size_t len, int flags)
1275+
{
1276+
struct sock *sk = sock->sk;
1277+
struct vsock_sock *vsk = vsock_sk(sk);
1278+
1279+
return vsk->transport->dgram_dequeue(vsk, msg, len, flags);
1280+
}
1281+
12731282
int vsock_dgram_recvmsg(struct socket *sock, struct msghdr *msg,
12741283
size_t len, int flags)
12751284
{
12761285
#ifdef CONFIG_BPF_SYSCALL
1286+
struct sock *sk = sock->sk;
12771287
const struct proto *prot;
1278-
#endif
1279-
struct vsock_sock *vsk;
1280-
struct sock *sk;
12811288

1282-
sk = sock->sk;
1283-
vsk = vsock_sk(sk);
1284-
1285-
#ifdef CONFIG_BPF_SYSCALL
12861289
prot = READ_ONCE(sk->sk_prot);
12871290
if (prot != &vsock_proto)
12881291
return prot->recvmsg(sk, msg, len, flags, NULL);
12891292
#endif
12901293

1291-
return vsk->transport->dgram_dequeue(vsk, msg, len, flags);
1294+
return __vsock_dgram_recvmsg(sock, msg, len, flags);
12921295
}
12931296
EXPORT_SYMBOL_GPL(vsock_dgram_recvmsg);
12941297

@@ -2174,15 +2177,12 @@ static int __vsock_seqpacket_recvmsg(struct sock *sk, struct msghdr *msg,
21742177
}
21752178

21762179
int
2177-
vsock_connectible_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
2178-
int flags)
2180+
__vsock_connectible_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
2181+
int flags)
21792182
{
21802183
struct sock *sk;
21812184
struct vsock_sock *vsk;
21822185
const struct vsock_transport *transport;
2183-
#ifdef CONFIG_BPF_SYSCALL
2184-
const struct proto *prot;
2185-
#endif
21862186
int err;
21872187

21882188
sk = sock->sk;
@@ -2233,14 +2233,6 @@ vsock_connectible_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
22332233
goto out;
22342234
}
22352235

2236-
#ifdef CONFIG_BPF_SYSCALL
2237-
prot = READ_ONCE(sk->sk_prot);
2238-
if (prot != &vsock_proto) {
2239-
release_sock(sk);
2240-
return prot->recvmsg(sk, msg, len, flags, NULL);
2241-
}
2242-
#endif
2243-
22442236
if (sk->sk_type == SOCK_STREAM)
22452237
err = __vsock_stream_recvmsg(sk, msg, len, flags);
22462238
else
@@ -2250,6 +2242,22 @@ vsock_connectible_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
22502242
release_sock(sk);
22512243
return err;
22522244
}
2245+
2246+
int
2247+
vsock_connectible_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
2248+
int flags)
2249+
{
2250+
#ifdef CONFIG_BPF_SYSCALL
2251+
struct sock *sk = sock->sk;
2252+
const struct proto *prot;
2253+
2254+
prot = READ_ONCE(sk->sk_prot);
2255+
if (prot != &vsock_proto)
2256+
return prot->recvmsg(sk, msg, len, flags, NULL);
2257+
#endif
2258+
2259+
return __vsock_connectible_recvmsg(sock, msg, len, flags);
2260+
}
22532261
EXPORT_SYMBOL_GPL(vsock_connectible_recvmsg);
22542262

22552263
static int vsock_set_rcvlowat(struct sock *sk, int val)

net/vmw_vsock/vsock_bpf.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ static int __vsock_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int
6464
int err;
6565

6666
if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET)
67-
err = vsock_connectible_recvmsg(sock, msg, len, flags);
67+
err = __vsock_connectible_recvmsg(sock, msg, len, flags);
6868
else if (sk->sk_type == SOCK_DGRAM)
69-
err = vsock_dgram_recvmsg(sock, msg, len, flags);
69+
err = __vsock_dgram_recvmsg(sock, msg, len, flags);
7070
else
7171
err = -EPROTOTYPE;
7272

0 commit comments

Comments
 (0)