three fixes, one for stable, one adds the (most secure) SMB3.1.1 dialect to default list requested

-----BEGIN PGP SIGNATURE-----
 
 iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAlwwD7EACgkQiiy9cAdy
 T1HVLwwAkjsxPoGSZD1S+corFexh50UZvEQXbEeuIa70h7nVFxGuONOB3TiOebWm
 xz//s6twlduOv+l82riV41W4iEcLT36If7lEl7JX1wVycY6MIm0KwzUqJKnDw60p
 zxNEkk6sQ+1wZ8fj6jonDsdtctGoGhNoWkPybyaYkersQFRBFSkPKnpvWF9bXRz0
 uqioONLpE2rajUJHv5gLE3dswTBvE2SGvCQfy0ANp3ZBVY5JGjyWlUQqC0riiemY
 P541VbJlXmcLeU5COg7Wz45BRlHHYxJVAKc74owS823kMUfHW2Zyae4gWmOhKT0S
 86CEYoZR+7nyegggNJr/sIC2ISftz1cr0q9VWeqXJSesNjGJFAbbqdh7qBf1sUMp
 SseUPwlhhe6LnfYt5scwj49V/BZQqPcxThBNNXfFQayCWSNUuIPSBQ+euGeGaVJf
 j1hhUq28DhbuGcz1464JnI06MCEpSyMAsKHNToK+EZLBH6lu6UcgcA2NHyF8mp/L
 IPyJhjTe
 =SZtN
 -----END PGP SIGNATURE-----

Merge tag '4.21-smb3-small-fixes' of git://git.samba.org/sfrench/cifs-2.6

Pull smb3 fixes from Steve French:
 "Three fixes, one for stable, one adds the (most secure) SMB3.1.1
  dialect to default list requested"

* tag '4.21-smb3-small-fixes' of git://git.samba.org/sfrench/cifs-2.6:
  smb3: add smb3.1.1 to default dialect list
  cifs: fix confusing warning message on reconnect
  smb3: fix large reads on encrypted connections
This commit is contained in:
Linus Torvalds 2019-01-05 14:05:06 -08:00
commit 7e928df80d
4 changed files with 32 additions and 16 deletions

View File

@ -483,7 +483,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
cifs_sb = NULL; cifs_sb = NULL;
} else { } else {
rc = reconn_setup_dfs_targets(cifs_sb, &tgt_list, &tgt_it); rc = reconn_setup_dfs_targets(cifs_sb, &tgt_list, &tgt_it);
if (rc) { if (rc && (rc != -EOPNOTSUPP)) {
cifs_dbg(VFS, "%s: no target servers for DFS failover\n", cifs_dbg(VFS, "%s: no target servers for DFS failover\n",
__func__); __func__);
} else { } else {

View File

@ -3472,8 +3472,10 @@ smb3_receive_transform(struct TCP_Server_Info *server,
} }
/* TODO: add support for compounds containing READ. */ /* TODO: add support for compounds containing READ. */
if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server)) if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server)) {
*num_mids = 1;
return receive_encrypted_read(server, &mids[0]); return receive_encrypted_read(server, &mids[0]);
}
return receive_encrypted_standard(server, mids, bufs, num_mids); return receive_encrypted_standard(server, mids, bufs, num_mids);
} }

View File

@ -451,10 +451,6 @@ smb2_plain_req_init(__le16 smb2_command, struct cifs_tcon *tcon,
} }
/* offset is sizeof smb2_negotiate_req but rounded up to 8 bytes */
#define OFFSET_OF_NEG_CONTEXT 0x68 /* sizeof(struct smb2_negotiate_req) */
#define SMB2_PREAUTH_INTEGRITY_CAPABILITIES cpu_to_le16(1) #define SMB2_PREAUTH_INTEGRITY_CAPABILITIES cpu_to_le16(1)
#define SMB2_ENCRYPTION_CAPABILITIES cpu_to_le16(2) #define SMB2_ENCRYPTION_CAPABILITIES cpu_to_le16(2)
#define SMB2_POSIX_EXTENSIONS_AVAILABLE cpu_to_le16(0x100) #define SMB2_POSIX_EXTENSIONS_AVAILABLE cpu_to_le16(0x100)
@ -491,10 +487,24 @@ static void
assemble_neg_contexts(struct smb2_negotiate_req *req, assemble_neg_contexts(struct smb2_negotiate_req *req,
unsigned int *total_len) unsigned int *total_len)
{ {
char *pneg_ctxt = (char *)req + OFFSET_OF_NEG_CONTEXT; char *pneg_ctxt = (char *)req;
unsigned int ctxt_len; unsigned int ctxt_len;
*total_len += 2; /* Add 2 due to round to 8 byte boundary for 1st ctxt */ if (*total_len > 200) {
/* In case length corrupted don't want to overrun smb buffer */
cifs_dbg(VFS, "Bad frame length assembling neg contexts\n");
return;
}
/*
* round up total_len of fixed part of SMB3 negotiate request to 8
* byte boundary before adding negotiate contexts
*/
*total_len = roundup(*total_len, 8);
pneg_ctxt = (*total_len) + (char *)req;
req->NegotiateContextOffset = cpu_to_le32(*total_len);
build_preauth_ctxt((struct smb2_preauth_neg_context *)pneg_ctxt); build_preauth_ctxt((struct smb2_preauth_neg_context *)pneg_ctxt);
ctxt_len = DIV_ROUND_UP(sizeof(struct smb2_preauth_neg_context), 8) * 8; ctxt_len = DIV_ROUND_UP(sizeof(struct smb2_preauth_neg_context), 8) * 8;
*total_len += ctxt_len; *total_len += ctxt_len;
@ -508,7 +518,6 @@ assemble_neg_contexts(struct smb2_negotiate_req *req,
build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt); build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt);
*total_len += sizeof(struct smb2_posix_neg_context); *total_len += sizeof(struct smb2_posix_neg_context);
req->NegotiateContextOffset = cpu_to_le32(OFFSET_OF_NEG_CONTEXT);
req->NegotiateContextCount = cpu_to_le16(3); req->NegotiateContextCount = cpu_to_le16(3);
} }
@ -724,8 +733,9 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
req->Dialects[0] = cpu_to_le16(SMB21_PROT_ID); req->Dialects[0] = cpu_to_le16(SMB21_PROT_ID);
req->Dialects[1] = cpu_to_le16(SMB30_PROT_ID); req->Dialects[1] = cpu_to_le16(SMB30_PROT_ID);
req->Dialects[2] = cpu_to_le16(SMB302_PROT_ID); req->Dialects[2] = cpu_to_le16(SMB302_PROT_ID);
req->DialectCount = cpu_to_le16(3); req->Dialects[3] = cpu_to_le16(SMB311_PROT_ID);
total_len += 6; req->DialectCount = cpu_to_le16(4);
total_len += 8;
} else { } else {
/* otherwise send specific dialect */ /* otherwise send specific dialect */
req->Dialects[0] = cpu_to_le16(ses->server->vals->protocol_id); req->Dialects[0] = cpu_to_le16(ses->server->vals->protocol_id);
@ -749,7 +759,9 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
else { else {
memcpy(req->ClientGUID, server->client_guid, memcpy(req->ClientGUID, server->client_guid,
SMB2_CLIENT_GUID_SIZE); SMB2_CLIENT_GUID_SIZE);
if (ses->server->vals->protocol_id == SMB311_PROT_ID) if ((ses->server->vals->protocol_id == SMB311_PROT_ID) ||
(strcmp(ses->server->vals->version_string,
SMBDEFAULT_VERSION_STRING) == 0))
assemble_neg_contexts(req, &total_len); assemble_neg_contexts(req, &total_len);
} }
iov[0].iov_base = (char *)req; iov[0].iov_base = (char *)req;
@ -794,7 +806,8 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
} else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) { } else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) {
/* ops set to 3.0 by default for default so update */ /* ops set to 3.0 by default for default so update */
ses->server->ops = &smb21_operations; ses->server->ops = &smb21_operations;
} } else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID))
ses->server->ops = &smb311_operations;
} else if (le16_to_cpu(rsp->DialectRevision) != } else if (le16_to_cpu(rsp->DialectRevision) !=
ses->server->vals->protocol_id) { ses->server->vals->protocol_id) {
/* if requested single dialect ensure returned dialect matched */ /* if requested single dialect ensure returned dialect matched */
@ -941,13 +954,14 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
pneg_inbuf->DialectCount = cpu_to_le16(2); pneg_inbuf->DialectCount = cpu_to_le16(2);
/* structure is big enough for 3 dialects, sending only 2 */ /* structure is big enough for 3 dialects, sending only 2 */
inbuflen = sizeof(*pneg_inbuf) - inbuflen = sizeof(*pneg_inbuf) -
sizeof(pneg_inbuf->Dialects[0]); (2 * sizeof(pneg_inbuf->Dialects[0]));
} else if (strcmp(tcon->ses->server->vals->version_string, } else if (strcmp(tcon->ses->server->vals->version_string,
SMBDEFAULT_VERSION_STRING) == 0) { SMBDEFAULT_VERSION_STRING) == 0) {
pneg_inbuf->Dialects[0] = cpu_to_le16(SMB21_PROT_ID); pneg_inbuf->Dialects[0] = cpu_to_le16(SMB21_PROT_ID);
pneg_inbuf->Dialects[1] = cpu_to_le16(SMB30_PROT_ID); pneg_inbuf->Dialects[1] = cpu_to_le16(SMB30_PROT_ID);
pneg_inbuf->Dialects[2] = cpu_to_le16(SMB302_PROT_ID); pneg_inbuf->Dialects[2] = cpu_to_le16(SMB302_PROT_ID);
pneg_inbuf->DialectCount = cpu_to_le16(3); pneg_inbuf->Dialects[3] = cpu_to_le16(SMB311_PROT_ID);
pneg_inbuf->DialectCount = cpu_to_le16(4);
/* structure is big enough for 3 dialects */ /* structure is big enough for 3 dialects */
inbuflen = sizeof(*pneg_inbuf); inbuflen = sizeof(*pneg_inbuf);
} else { } else {

View File

@ -898,7 +898,7 @@ struct validate_negotiate_info_req {
__u8 Guid[SMB2_CLIENT_GUID_SIZE]; __u8 Guid[SMB2_CLIENT_GUID_SIZE];
__le16 SecurityMode; __le16 SecurityMode;
__le16 DialectCount; __le16 DialectCount;
__le16 Dialects[3]; /* BB expand this if autonegotiate > 3 dialects */ __le16 Dialects[4]; /* BB expand this if autonegotiate > 4 dialects */
} __packed; } __packed;
struct validate_negotiate_info_rsp { struct validate_negotiate_info_rsp {