Add cifs fix present in queue-3.2/series but not in the repo
diff --git a/queue-3.2/cifs-dynamic-allocation-of-ntlmssp-blob.patch b/queue-3.2/cifs-dynamic-allocation-of-ntlmssp-blob.patch
new file mode 100644
index 0000000..8c0ea76
--- /dev/null
+++ b/queue-3.2/cifs-dynamic-allocation-of-ntlmssp-blob.patch
@@ -0,0 +1,202 @@
+From: Jerome Marchand <jmarchan@redhat.com>
+Date: Thu, 26 May 2016 11:52:25 +0200
+Subject: cifs: dynamic allocation of ntlmssp blob
+
+commit b8da344b74c822e966c6d19d6b2321efe82c5d97 upstream.
+
+In sess_auth_rawntlmssp_authenticate(), the ntlmssp blob is allocated
+statically and its size is an "empirical" 5*sizeof(struct
+_AUTHENTICATE_MESSAGE) (320B on x86_64). I don't know where this value
+comes from or if it was ever appropriate, but it is currently
+insufficient: the user and domain name in UTF16 could take 1kB by
+themselves. Because of that, build_ntlmssp_auth_blob() might corrupt
+memory (out-of-bounds write). The size of ntlmssp_blob in
+SMB2_sess_setup() is too small too (sizeof(struct _NEGOTIATE_MESSAGE)
++ 500).
+
+This patch allocates the blob dynamically in
+build_ntlmssp_auth_blob().
+
+Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
+Signed-off-by: Steve French <smfrench@gmail.com>
+[bwh: Backported to 3.2:
+ - Adjust context, indentation
+ - build_ntlmssp_auth_blob() is static
+ - Drop changes to smb2pdu.c
+ - Use cERROR() instead of cifs_dbg(VFS, ...)
+ - Use MAX_USERNAME_SIZE instead of CIFS_MAX_USERNAME_LEN]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+--- a/fs/cifs/sess.c
++++ b/fs/cifs/sess.c
+@@ -444,19 +444,43 @@ static void build_ntlmssp_negotiate_blob
+ 	sec_blob->DomainName.MaximumLength = 0;
+ }
+ 
+-/* We do not malloc the blob, it is passed in pbuffer, because its
+-   maximum possible size is fixed and small, making this approach cleaner.
+-   This function returns the length of the data in the blob */
+-static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
++static int size_of_ntlmssp_blob(struct cifs_ses *ses)
++{
++	int sz = sizeof(AUTHENTICATE_MESSAGE) + ses->auth_key.len
++		- CIFS_SESS_KEY_SIZE + CIFS_CPHTXT_SIZE + 2;
++
++	if (ses->domainName)
++		sz += 2 * strnlen(ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
++	else
++		sz += 2;
++
++	if (ses->user_name)
++		sz += 2 * strnlen(ses->user_name, MAX_USERNAME_SIZE);
++	else
++		sz += 2;
++
++	return sz;
++}
++
++static int build_ntlmssp_auth_blob(unsigned char **pbuffer,
+ 					u16 *buflen,
+ 				   struct cifs_ses *ses,
+ 				   const struct nls_table *nls_cp)
+ {
+ 	int rc;
+-	AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer;
++	AUTHENTICATE_MESSAGE *sec_blob;
+ 	__u32 flags;
+ 	unsigned char *tmp;
+ 
++	rc = setup_ntlmv2_rsp(ses, nls_cp);
++	if (rc) {
++		cERROR(1, "Error %d during NTLMSSP authentication", rc);
++		*buflen = 0;
++		goto setup_ntlmv2_ret;
++	}
++	*pbuffer = kmalloc(size_of_ntlmssp_blob(ses), GFP_KERNEL);
++	sec_blob = (AUTHENTICATE_MESSAGE *)*pbuffer;
++
+ 	memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
+ 	sec_blob->MessageType = NtLmAuthenticate;
+ 
+@@ -471,7 +495,7 @@ static int build_ntlmssp_auth_blob(unsig
+ 			flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
+ 	}
+ 
+-	tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE);
++	tmp = *pbuffer + sizeof(AUTHENTICATE_MESSAGE);
+ 	sec_blob->NegotiateFlags = cpu_to_le32(flags);
+ 
+ 	sec_blob->LmChallengeResponse.BufferOffset =
+@@ -479,13 +503,9 @@ static int build_ntlmssp_auth_blob(unsig
+ 	sec_blob->LmChallengeResponse.Length = 0;
+ 	sec_blob->LmChallengeResponse.MaximumLength = 0;
+ 
+-	sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer);
++	sec_blob->NtChallengeResponse.BufferOffset =
++				cpu_to_le32(tmp - *pbuffer);
+ 	if (ses->user_name != NULL) {
+-		rc = setup_ntlmv2_rsp(ses, nls_cp);
+-		if (rc) {
+-			cERROR(1, "Error %d during NTLMSSP authentication", rc);
+-			goto setup_ntlmv2_ret;
+-		}
+ 		memcpy(tmp, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
+ 				ses->auth_key.len - CIFS_SESS_KEY_SIZE);
+ 		tmp += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
+@@ -503,7 +523,7 @@ static int build_ntlmssp_auth_blob(unsig
+ 	}
+ 
+ 	if (ses->domainName == NULL) {
+-		sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
++		sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
+ 		sec_blob->DomainName.Length = 0;
+ 		sec_blob->DomainName.MaximumLength = 0;
+ 		tmp += 2;
+@@ -512,14 +532,14 @@ static int build_ntlmssp_auth_blob(unsig
+ 		len = cifs_strtoUCS((__le16 *)tmp, ses->domainName,
+ 				    MAX_USERNAME_SIZE, nls_cp);
+ 		len *= 2; /* unicode is 2 bytes each */
+-		sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
++		sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
+ 		sec_blob->DomainName.Length = cpu_to_le16(len);
+ 		sec_blob->DomainName.MaximumLength = cpu_to_le16(len);
+ 		tmp += len;
+ 	}
+ 
+ 	if (ses->user_name == NULL) {
+-		sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
++		sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
+ 		sec_blob->UserName.Length = 0;
+ 		sec_blob->UserName.MaximumLength = 0;
+ 		tmp += 2;
+@@ -528,13 +548,13 @@ static int build_ntlmssp_auth_blob(unsig
+ 		len = cifs_strtoUCS((__le16 *)tmp, ses->user_name,
+ 				    MAX_USERNAME_SIZE, nls_cp);
+ 		len *= 2; /* unicode is 2 bytes each */
+-		sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
++		sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
+ 		sec_blob->UserName.Length = cpu_to_le16(len);
+ 		sec_blob->UserName.MaximumLength = cpu_to_le16(len);
+ 		tmp += len;
+ 	}
+ 
+-	sec_blob->WorkstationName.BufferOffset = cpu_to_le32(tmp - pbuffer);
++	sec_blob->WorkstationName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
+ 	sec_blob->WorkstationName.Length = 0;
+ 	sec_blob->WorkstationName.MaximumLength = 0;
+ 	tmp += 2;
+@@ -543,19 +563,19 @@ static int build_ntlmssp_auth_blob(unsig
+ 		(ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
+ 			&& !calc_seckey(ses)) {
+ 		memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
+-		sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
++		sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - *pbuffer);
+ 		sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);
+ 		sec_blob->SessionKey.MaximumLength =
+ 				cpu_to_le16(CIFS_CPHTXT_SIZE);
+ 		tmp += CIFS_CPHTXT_SIZE;
+ 	} else {
+-		sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
++		sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - *pbuffer);
+ 		sec_blob->SessionKey.Length = 0;
+ 		sec_blob->SessionKey.MaximumLength = 0;
+ 	}
+ 
++	*buflen = tmp - *pbuffer;
+ setup_ntlmv2_ret:
+-	*buflen = tmp - pbuffer;
+ 	return rc;
+ }
+ 
+@@ -578,7 +598,7 @@ CIFS_SessSetup(unsigned int xid, struct
+ 	struct key *spnego_key = NULL;
+ 	__le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */
+ 	u16 blob_len;
+-	char *ntlmsspblob = NULL;
++	unsigned char *ntlmsspblob = NULL;
+ 
+ 	if (ses == NULL)
+ 		return -EINVAL;
+@@ -832,21 +852,7 @@ ssetup_ntlmssp_authenticate:
+ 				cpu_to_le16(sizeof(NEGOTIATE_MESSAGE));
+ 			break;
+ 		case NtLmAuthenticate:
+-			/*
+-			 * 5 is an empirical value, large enough to hold
+-			 * authenticate message plus max 10 of av paris,
+-			 * domain, user, workstation names, flags, etc.
+-			 */
+-			ntlmsspblob = kzalloc(
+-				5*sizeof(struct _AUTHENTICATE_MESSAGE),
+-				GFP_KERNEL);
+-			if (!ntlmsspblob) {
+-				cERROR(1, "Can't allocate NTLMSSP blob");
+-				rc = -ENOMEM;
+-				goto ssetup_exit;
+-			}
+-
+-			rc = build_ntlmssp_auth_blob(ntlmsspblob,
++			rc = build_ntlmssp_auth_blob(&ntlmsspblob,
+ 						&blob_len, ses, nls_cp);
+ 			if (rc)
+ 				goto ssetup_exit;