A non-blocking connect() running in parallel with a blocking connect(),
combined with a racy listen() that hits right after a connect timeout:
TCP_SYN_SENT -> TCP_CLOSE -> TCP_LISTEN, while the connect() loop is still
in progress.
Enforce the invariant. Prevent a socket from becoming a listener after
acquiring a transport.
Fixes: c0cfa2d8a788 ("vsock: add multi-transports support")
Signed-off-by: Michal Luczaj <[email protected]>
---
net/vmw_vsock/af_vsock.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index f840498b58af..499e902becfa 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -1973,13 +1973,13 @@ static int vsock_listen(struct socket *sock, int
backlog)
goto out;
}
- if (sock->state != SS_UNCONNECTED) {
+ vsk = vsock_sk(sk);
+
+ if (sock->state != SS_UNCONNECTED || vsk->transport) {
err = -EINVAL;
goto out;
}
- vsk = vsock_sk(sk);
-
if (!vsock_addr_bound(&vsk->local_addr)) {
err = -EINVAL;
goto out;
--
2.55.0