Skip to content

Commit

Permalink
cifs: eliminate some more premature cifsd exits
Browse files Browse the repository at this point in the history
If the tcpStatus is still CifsNew, the main cifs_demultiplex_loop can
break out prematurely in some cases. This is wrong as we will almost
always have other structures with pointers to the TCP_Server_Info. If
the main loop breaks under any other condition other than tcpStatus ==
CifsExiting, then it'll face a use-after-free situation.

I don't see any reason to treat a CifsNew tcpStatus differently than
CifsGood. I believe we'll still want to attempt to reconnect in either
case. What should happen in those situations is that the MIDs get marked
as MID_RETRY_NEEDED. This will make CIFSSMBNegotiate return -EAGAIN, and
then the caller can retry the whole thing on a newly reconnected socket.
If that fails again in the same way, the caller of cifs_get_smb_ses
should tear down the TCP_Server_Info struct.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
  • Loading branch information
Jeff Layton authored and Steve French committed Sep 8, 2010
1 parent 522bbe6 commit 7332f2a
Showing 1 changed file with 12 additions and 29 deletions.
41 changes: 12 additions & 29 deletions fs/cifs/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -416,14 +416,6 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
} else
continue;
} else if (length <= 0) {
if (server->tcpStatus == CifsNew) {
cFYI(1, "tcp session abend after SMBnegprot");
/* some servers kill the TCP session rather than
returning an SMB negprot error, in which
case reconnecting here is not going to help,
and so simply return error to mount */
break;
}
cFYI(1, "Reconnect after unexpected peek error %d",
length);
cifs_reconnect(server);
Expand Down Expand Up @@ -464,27 +456,18 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
an error on SMB negprot response */
cFYI(1, "Negative RFC1002 Session Response Error 0x%x)",
pdu_length);
if (server->tcpStatus == CifsNew) {
/* if nack on negprot (rather than
ret of smb negprot error) reconnecting
not going to help, ret error to mount */
break;
} else {
/* give server a second to
clean up before reconnect attempt */
msleep(1000);
/* always try 445 first on reconnect
since we get NACK on some if we ever
connected to port 139 (the NACK is
since we do not begin with RFC1001
session initialize frame) */
server->addr.sockAddr.sin_port =
htons(CIFS_PORT);
cifs_reconnect(server);
csocket = server->ssocket;
wake_up(&server->response_q);
continue;
}
/* give server a second to clean up */
msleep(1000);
/* always try 445 first on reconnect since we get NACK
* on some if we ever connected to port 139 (the NACK
* is since we do not begin with RFC1001 session
* initialize frame)
*/
server->addr.sockAddr.sin_port = htons(CIFS_PORT);
cifs_reconnect(server);
csocket = server->ssocket;
wake_up(&server->response_q);
continue;
} else if (temp != (char) 0) {
cERROR(1, "Unknown RFC 1002 frame");
cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
Expand Down

0 comments on commit 7332f2a

Please sign in to comment.