Skip to contentSkip to conversation

net/smc: restrict non-blocking connect finish

PATCH In review Ursula Braun 2 participants 2 messages May 2, 2018

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 net/smc: restrict non-blocking connect finish

The smc_poll code tries to finish connect() if the socket is in state SMC_INIT and polling of the internal CLC-socket returns with EPOLLOUT. This makes sense for a select/poll call following a connect call, but not without preceding connect().
With this patch smc_poll starts connect logic only, if the CLC-socket is no longer in its initial state TCP_CLOSE.

In addition, a poll error on the internal CLC-socket is always propagated to the SMC socket.

With this patch the code path mentioned by syzbot
https://syzkaller.appspot.com/bug?extid=03faa2dc16b8b64be396
is no longer possible.

---
 net/smc/af_smc.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)
net/smc/af_smc.c +8 -6
index 4470501374bf..8b4c059bd13b 100644
@@ -1166,13 +1166,15 @@ static __poll_t smc_poll(struct file *file, struct socket *sock,
 		/* delegate to CLC child sock */
 		release_sock(sk);
 		mask = smc->clcsock->ops->poll(file, smc->clcsock, wait);
-		/* if non-blocking connect finished ... */
 		lock_sock(sk);
-		if ((sk->sk_state == SMC_INIT) && (mask & EPOLLOUT)) {
-			sk->sk_err = smc->clcsock->sk->sk_err;
-			if (sk->sk_err) {
-				mask |= EPOLLERR;
-			} else {
+		sk->sk_err = smc->clcsock->sk->sk_err;
+		if (sk->sk_err) {
+			mask |= EPOLLERR;
+		} else {
+			/* if non-blocking connect finished ... */
+			if (sk->sk_state == SMC_INIT &&
+			    mask & EPOLLOUT &&
+			    smc->clcsock->sk->sk_state != TCP_CLOSE) {
 				rc = smc_connect_rdma(smc);
 				if (rc < 0)
 					mask |= EPOLLERR;
Signature · 1 line
2.13.5
maintainer
#1 lore raw

From: Ursula Braun <[email protected]>
Date: Wed, 2 May 2018 16:53:56 +0200

Quoted 10 lines

The smc_poll code tries to finish connect() if the socket is in state SMC_INIT and polling of the internal CLC-socket returns with EPOLLOUT. This makes sense for a select/poll call following a connect call, but not without preceding connect().
With this patch smc_poll starts connect logic only, if the CLC-socket is no longer in its initial state TCP_CLOSE.

In addition, a poll error on the internal CLC-socket is always propagated to the SMC socket.

Quoted 6 lines

With this patch the code path mentioned by syzbot
https://syzkaller.appspot.com/bug?extid=03faa2dc16b8b64be396
is no longer possible.

Applied and queued up for -stable, thanks.