diff mbox

CIFS: Fix race condition on RFC1002_NEGATIVE_SESSION_RESPONSE

Message ID 5538E6F4.6010105@innominate.com (mailing list archive)
State New, archived
Headers show

Commit Message

Federico Sauter April 23, 2015, 12:35 p.m. UTC
Any feedback on whether this patch makes sense or not? ;-)

---8<----------------------------------------------------------------------
 >From 54e3c95a4646c8666c6f08766250fd056b06e7f5 Mon Sep 17 00:00:00 2001
From: Federico Sauter <fsauter@innominate.com>
Date: Tue, 17 Mar 2015 17:45:28 +0100
Subject: [PATCH] CIFS: Fix race condition on
  RFC1002_NEGATIVE_SESSION_RESPONSE

This patch fixes a race condition that occurs when connecting
to a NT 3.51 host without specifying a NetBIOS name.
In that case a RFC1002_NEGATIVE_SESSION_RESPONSE is received
and the SMB negotiation is reattempted, but under some conditions
it leads SendReceive() to hang forever while waiting for srv_mutex.
This, in turn, sets the calling process to an uninterruptible sleep
state and makes it unkillable.

The solution is to unlock the srv_mutex acquired in the demux
thread *before* going to sleep (after the reconnect error) and
before reattempting the connection.
---
  fs/cifs/connect.c |    3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)
diff mbox

Patch

diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index d05a300..a45e7fc 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -381,6 +381,7 @@  cifs_reconnect(struct TCP_Server_Info *server)
  		rc = generic_ip_connect(server);
  		if (rc) {
  			cifs_dbg(FYI, "reconnect error %d\n", rc);
+			mutex_unlock(&server->srv_mutex);
  			msleep(3000);
  		} else {
  			atomic_inc(&tcpSesReconnectCount);
@@ -388,8 +389,8 @@  cifs_reconnect(struct TCP_Server_Info *server)
  			if (server->tcpStatus != CifsExiting)
  				server->tcpStatus = CifsNeedNegotiate;
  			spin_unlock(&GlobalMid_Lock);
+			mutex_unlock(&server->srv_mutex);
  		}
-		mutex_unlock(&server->srv_mutex);
  	} while (server->tcpStatus == CifsNeedReconnect);

  	return rc;