Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7332f2a6 authored by Jeff Layton's avatar Jeff Layton Committed by Steve French
Browse files

cifs: eliminate some more premature cifsd exits



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: default avatarJeff Layton <jlayton@redhat.com>
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent 522bbe65
Loading
Loading
Loading
Loading
+12 −29
Original line number Original line Diff line number Diff line
@@ -416,14 +416,6 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
			} else
			} else
				continue;
				continue;
		} else if (length <= 0) {
		} 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",
			cFYI(1, "Reconnect after unexpected peek error %d",
				length);
				length);
			cifs_reconnect(server);
			cifs_reconnect(server);
@@ -464,27 +456,18 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
			   an error on SMB negprot response */
			   an error on SMB negprot response */
			cFYI(1, "Negative RFC1002 Session Response Error 0x%x)",
			cFYI(1, "Negative RFC1002 Session Response Error 0x%x)",
				pdu_length);
				pdu_length);
			if (server->tcpStatus == CifsNew) {
			/* give server a second to clean up  */
				/* 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);
			msleep(1000);
				/* always try 445 first on reconnect
			/* always try 445 first on reconnect since we get NACK
				since we get NACK on some if we ever
			 * on some if we ever connected to port 139 (the NACK
				connected to port 139 (the NACK is
			 * is since we do not begin with RFC1001 session
				since we do not begin with RFC1001
			 * initialize frame)
				session initialize frame) */
			 */
				server->addr.sockAddr.sin_port =
			server->addr.sockAddr.sin_port = htons(CIFS_PORT);
					htons(CIFS_PORT);
			cifs_reconnect(server);
			cifs_reconnect(server);
			csocket = server->ssocket;
			csocket = server->ssocket;
			wake_up(&server->response_q);
			wake_up(&server->response_q);
			continue;
			continue;
			}
		} else if (temp != (char) 0) {
		} else if (temp != (char) 0) {
			cERROR(1, "Unknown RFC 1002 frame");
			cERROR(1, "Unknown RFC 1002 frame");
			cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
			cifs_dump_mem(" Received Data: ", (char *)smb_buffer,