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

Commit 93012bf9 authored by Ronnie Sahlberg's avatar Ronnie Sahlberg Committed by Steve French
Browse files

cifs: add server->vals->header_preamble_size



This variable is set to 4 for all protocol versions and replaces
the hardcoded constant 4 throughought the code.
This will later be updated to reflect whether a response packet
has a 4 byte length preamble or not once we start removing this
field from the SMB2+ dialects.

Signed-off-by: default avatarRonnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
Reviewed-by: default avatarPavel Shilovsky <pshilov@microsoft.com>
parent 21a4e14a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -468,6 +468,7 @@ struct smb_version_values {
	__u32		exclusive_lock_type;
	__u32		shared_lock_type;
	__u32		unlock_lock_type;
	size_t		header_preamble_size;
	size_t		header_size;
	size_t		max_header_size;
	size_t		read_rsp_size;
+4 −2
Original line number Diff line number Diff line
@@ -1454,7 +1454,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
	unsigned int data_offset, data_len;
	struct cifs_readdata *rdata = mid->callback_data;
	char *buf = server->smallbuf;
	unsigned int buflen = get_rfc1002_length(buf) + 4;
	unsigned int buflen = get_rfc1002_length(buf) +
		server->vals->header_preamble_size;
	bool use_rdma_mr = false;

	cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n",
@@ -1504,7 +1505,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
		return cifs_readv_discard(server, mid);
	}

	data_offset = server->ops->read_data_offset(buf) + 4;
	data_offset = server->ops->read_data_offset(buf) +
		server->vals->header_preamble_size;
	if (data_offset < server->total_read) {
		/*
		 * win2k8 sometimes sends an offset of 0 when the read
+11 −5
Original line number Diff line number Diff line
@@ -775,7 +775,8 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid)
	unsigned int pdu_length = get_rfc1002_length(buf);

	/* make sure this will fit in a large buffer */
	if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server) - 4) {
	if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server) -
		server->vals->header_preamble_size) {
		cifs_dbg(VFS, "SMB response too long (%u bytes)\n", pdu_length);
		cifs_reconnect(server);
		wake_up(&server->response_q);
@@ -791,7 +792,9 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid)

	/* now read the rest */
	length = cifs_read_from_socket(server, buf + HEADER_SIZE(server) - 1,
				pdu_length - HEADER_SIZE(server) + 1 + 4);
				       pdu_length - HEADER_SIZE(server) + 1
				       + server->vals->header_preamble_size);

	if (length < 0)
		return length;
	server->total_read += length;
@@ -884,7 +887,8 @@ cifs_demultiplex_thread(void *p)
			continue;

		/* make sure we have enough to get to the MID */
		if (pdu_length < HEADER_SIZE(server) - 1 - 4) {
		if (pdu_length < HEADER_SIZE(server) - 1 -
		    server->vals->header_preamble_size) {
			cifs_dbg(VFS, "SMB response too short (%u bytes)\n",
				 pdu_length);
			cifs_reconnect(server);
@@ -893,8 +897,10 @@ cifs_demultiplex_thread(void *p)
		}

		/* read down to the MID */
		length = cifs_read_from_socket(server, buf + 4,
					       HEADER_SIZE(server) - 1 - 4);
		length = cifs_read_from_socket(server,
			     buf + server->vals->header_preamble_size,
			     HEADER_SIZE(server) - 1
			     - server->vals->header_preamble_size);
		if (length < 0)
			continue;
		server->total_read += length;
+1 −0
Original line number Diff line number Diff line
@@ -1122,6 +1122,7 @@ struct smb_version_values smb1_values = {
	.exclusive_lock_type = 0,
	.shared_lock_type = LOCKING_ANDX_SHARED_LOCK,
	.unlock_lock_type = 0,
	.header_preamble_size = 4,
	.header_size = sizeof(struct smb_hdr),
	.max_header_size = MAX_CIFS_HDR_SIZE,
	.read_rsp_size = sizeof(READ_RSP),
+10 −9
Original line number Diff line number Diff line
@@ -150,7 +150,8 @@ smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr)
		}
		return 1;
	}
	if (len > CIFSMaxBufSize + MAX_SMB2_HDR_SIZE - 4) {
	if (len > CIFSMaxBufSize + MAX_SMB2_HDR_SIZE -
	    srvr->vals->header_preamble_size) {
		cifs_dbg(VFS, "SMB length greater than maximum, mid=%llu\n",
			 mid);
		return 1;
@@ -189,26 +190,26 @@ smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr)
		}
	}

	if (4 + len != length) {
	if (srvr->vals->header_preamble_size + len != length) {
		cifs_dbg(VFS, "Total length %u RFC1002 length %u mismatch mid %llu\n",
			 length, 4 + len, mid);
			 length, srvr->vals->header_preamble_size + len, mid);
		return 1;
	}

	clc_len = smb2_calc_size(hdr);

	if (4 + len != clc_len) {
	if (srvr->vals->header_preamble_size + len != clc_len) {
		cifs_dbg(FYI, "Calculated size %u length %u mismatch mid %llu\n",
			 clc_len, 4 + len, mid);
			 clc_len, srvr->vals->header_preamble_size + len, mid);
		/* create failed on symlink */
		if (command == SMB2_CREATE_HE &&
		    shdr->Status == STATUS_STOPPED_ON_SYMLINK)
			return 0;
		/* Windows 7 server returns 24 bytes more */
		if (clc_len + 20 == len && command == SMB2_OPLOCK_BREAK_HE)
		if (clc_len + 24 - srvr->vals->header_preamble_size == len && command == SMB2_OPLOCK_BREAK_HE)
			return 0;
		/* server can return one byte more due to implied bcc[0] */
		if (clc_len == 4 + len + 1)
		if (clc_len == srvr->vals->header_preamble_size + len + 1)
			return 0;

		/*
@@ -218,10 +219,10 @@ smb2_check_message(char *buf, unsigned int length, struct TCP_Server_Info *srvr)
		 * Log the server error (once), but allow it and continue
		 * since the frame is parseable.
		 */
		if (clc_len < 4 /* RFC1001 header size */ + len) {
		if (clc_len < srvr->vals->header_preamble_size /* RFC1001 header size */ + len) {
			printk_once(KERN_WARNING
				"SMB2 server sent bad RFC1001 len %d not %d\n",
				len, clc_len - 4);
				len, clc_len - srvr->vals->header_preamble_size);
			return 0;
		}

Loading