aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-01-05 17:05:06 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2019-01-05 17:05:06 -0500
commit7e928df80d30b7664b5822784c95b4a54dc7cfbf (patch)
tree6926184cd629693315c0061bce310db4b9de6165
parent3cd6d495db2a0acfd2854f43aac8bfc5914bc89c (diff)
parentd5c7076b772ad7dcdb92303397b36aee8fa0d25d (diff)
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
-rw-r--r--fs/cifs/connect.c2
-rw-r--r--fs/cifs/smb2ops.c4
-rw-r--r--fs/cifs/smb2pdu.c40
-rw-r--r--fs/cifs/smb2pdu.h2
4 files changed, 32 insertions, 16 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 69b9d5606eba..f66529679ca2 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -483,7 +483,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
483 cifs_sb = NULL; 483 cifs_sb = NULL;
484 } else { 484 } else {
485 rc = reconn_setup_dfs_targets(cifs_sb, &tgt_list, &tgt_it); 485 rc = reconn_setup_dfs_targets(cifs_sb, &tgt_list, &tgt_it);
486 if (rc) { 486 if (rc && (rc != -EOPNOTSUPP)) {
487 cifs_dbg(VFS, "%s: no target servers for DFS failover\n", 487 cifs_dbg(VFS, "%s: no target servers for DFS failover\n",
488 __func__); 488 __func__);
489 } else { 489 } else {
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 33100ef74d7f..cf7eb891804f 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -3472,8 +3472,10 @@ smb3_receive_transform(struct TCP_Server_Info *server,
3472 } 3472 }
3473 3473
3474 /* TODO: add support for compounds containing READ. */ 3474 /* TODO: add support for compounds containing READ. */
3475 if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server)) 3475 if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server)) {
3476 *num_mids = 1;
3476 return receive_encrypted_read(server, &mids[0]); 3477 return receive_encrypted_read(server, &mids[0]);
3478 }
3477 3479
3478 return receive_encrypted_standard(server, mids, bufs, num_mids); 3480 return receive_encrypted_standard(server, mids, bufs, num_mids);
3479} 3481}
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index e283590955cd..e57f6aa1d638 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -451,10 +451,6 @@ smb2_plain_req_init(__le16 smb2_command, struct cifs_tcon *tcon,
451} 451}
452 452
453 453
454/* offset is sizeof smb2_negotiate_req but rounded up to 8 bytes */
455#define OFFSET_OF_NEG_CONTEXT 0x68 /* sizeof(struct smb2_negotiate_req) */
456
457
458#define SMB2_PREAUTH_INTEGRITY_CAPABILITIES cpu_to_le16(1) 454#define SMB2_PREAUTH_INTEGRITY_CAPABILITIES cpu_to_le16(1)
459#define SMB2_ENCRYPTION_CAPABILITIES cpu_to_le16(2) 455#define SMB2_ENCRYPTION_CAPABILITIES cpu_to_le16(2)
460#define SMB2_POSIX_EXTENSIONS_AVAILABLE cpu_to_le16(0x100) 456#define SMB2_POSIX_EXTENSIONS_AVAILABLE cpu_to_le16(0x100)
@@ -491,10 +487,24 @@ static void
491assemble_neg_contexts(struct smb2_negotiate_req *req, 487assemble_neg_contexts(struct smb2_negotiate_req *req,
492 unsigned int *total_len) 488 unsigned int *total_len)
493{ 489{
494 char *pneg_ctxt = (char *)req + OFFSET_OF_NEG_CONTEXT; 490 char *pneg_ctxt = (char *)req;
495 unsigned int ctxt_len; 491 unsigned int ctxt_len;
496 492
497 *total_len += 2; /* Add 2 due to round to 8 byte boundary for 1st ctxt */ 493 if (*total_len > 200) {
494 /* In case length corrupted don't want to overrun smb buffer */
495 cifs_dbg(VFS, "Bad frame length assembling neg contexts\n");
496 return;
497 }
498
499 /*
500 * round up total_len of fixed part of SMB3 negotiate request to 8
501 * byte boundary before adding negotiate contexts
502 */
503 *total_len = roundup(*total_len, 8);
504
505 pneg_ctxt = (*total_len) + (char *)req;
506 req->NegotiateContextOffset = cpu_to_le32(*total_len);
507
498 build_preauth_ctxt((struct smb2_preauth_neg_context *)pneg_ctxt); 508 build_preauth_ctxt((struct smb2_preauth_neg_context *)pneg_ctxt);
499 ctxt_len = DIV_ROUND_UP(sizeof(struct smb2_preauth_neg_context), 8) * 8; 509 ctxt_len = DIV_ROUND_UP(sizeof(struct smb2_preauth_neg_context), 8) * 8;
500 *total_len += ctxt_len; 510 *total_len += ctxt_len;
@@ -508,7 +518,6 @@ assemble_neg_contexts(struct smb2_negotiate_req *req,
508 build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt); 518 build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt);
509 *total_len += sizeof(struct smb2_posix_neg_context); 519 *total_len += sizeof(struct smb2_posix_neg_context);
510 520
511 req->NegotiateContextOffset = cpu_to_le32(OFFSET_OF_NEG_CONTEXT);
512 req->NegotiateContextCount = cpu_to_le16(3); 521 req->NegotiateContextCount = cpu_to_le16(3);
513} 522}
514 523
@@ -724,8 +733,9 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
724 req->Dialects[0] = cpu_to_le16(SMB21_PROT_ID); 733 req->Dialects[0] = cpu_to_le16(SMB21_PROT_ID);
725 req->Dialects[1] = cpu_to_le16(SMB30_PROT_ID); 734 req->Dialects[1] = cpu_to_le16(SMB30_PROT_ID);
726 req->Dialects[2] = cpu_to_le16(SMB302_PROT_ID); 735 req->Dialects[2] = cpu_to_le16(SMB302_PROT_ID);
727 req->DialectCount = cpu_to_le16(3); 736 req->Dialects[3] = cpu_to_le16(SMB311_PROT_ID);
728 total_len += 6; 737 req->DialectCount = cpu_to_le16(4);
738 total_len += 8;
729 } else { 739 } else {
730 /* otherwise send specific dialect */ 740 /* otherwise send specific dialect */
731 req->Dialects[0] = cpu_to_le16(ses->server->vals->protocol_id); 741 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)
749 else { 759 else {
750 memcpy(req->ClientGUID, server->client_guid, 760 memcpy(req->ClientGUID, server->client_guid,
751 SMB2_CLIENT_GUID_SIZE); 761 SMB2_CLIENT_GUID_SIZE);
752 if (ses->server->vals->protocol_id == SMB311_PROT_ID) 762 if ((ses->server->vals->protocol_id == SMB311_PROT_ID) ||
763 (strcmp(ses->server->vals->version_string,
764 SMBDEFAULT_VERSION_STRING) == 0))
753 assemble_neg_contexts(req, &total_len); 765 assemble_neg_contexts(req, &total_len);
754 } 766 }
755 iov[0].iov_base = (char *)req; 767 iov[0].iov_base = (char *)req;
@@ -794,7 +806,8 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
794 } else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) { 806 } else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) {
795 /* ops set to 3.0 by default for default so update */ 807 /* ops set to 3.0 by default for default so update */
796 ses->server->ops = &smb21_operations; 808 ses->server->ops = &smb21_operations;
797 } 809 } else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID))
810 ses->server->ops = &smb311_operations;
798 } else if (le16_to_cpu(rsp->DialectRevision) != 811 } else if (le16_to_cpu(rsp->DialectRevision) !=
799 ses->server->vals->protocol_id) { 812 ses->server->vals->protocol_id) {
800 /* if requested single dialect ensure returned dialect matched */ 813 /* if requested single dialect ensure returned dialect matched */
@@ -941,13 +954,14 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
941 pneg_inbuf->DialectCount = cpu_to_le16(2); 954 pneg_inbuf->DialectCount = cpu_to_le16(2);
942 /* structure is big enough for 3 dialects, sending only 2 */ 955 /* structure is big enough for 3 dialects, sending only 2 */
943 inbuflen = sizeof(*pneg_inbuf) - 956 inbuflen = sizeof(*pneg_inbuf) -
944 sizeof(pneg_inbuf->Dialects[0]); 957 (2 * sizeof(pneg_inbuf->Dialects[0]));
945 } else if (strcmp(tcon->ses->server->vals->version_string, 958 } else if (strcmp(tcon->ses->server->vals->version_string,
946 SMBDEFAULT_VERSION_STRING) == 0) { 959 SMBDEFAULT_VERSION_STRING) == 0) {
947 pneg_inbuf->Dialects[0] = cpu_to_le16(SMB21_PROT_ID); 960 pneg_inbuf->Dialects[0] = cpu_to_le16(SMB21_PROT_ID);
948 pneg_inbuf->Dialects[1] = cpu_to_le16(SMB30_PROT_ID); 961 pneg_inbuf->Dialects[1] = cpu_to_le16(SMB30_PROT_ID);
949 pneg_inbuf->Dialects[2] = cpu_to_le16(SMB302_PROT_ID); 962 pneg_inbuf->Dialects[2] = cpu_to_le16(SMB302_PROT_ID);
950 pneg_inbuf->DialectCount = cpu_to_le16(3); 963 pneg_inbuf->Dialects[3] = cpu_to_le16(SMB311_PROT_ID);
964 pneg_inbuf->DialectCount = cpu_to_le16(4);
951 /* structure is big enough for 3 dialects */ 965 /* structure is big enough for 3 dialects */
952 inbuflen = sizeof(*pneg_inbuf); 966 inbuflen = sizeof(*pneg_inbuf);
953 } else { 967 } else {
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
index 05dea6750c33..7a2d0a2255e6 100644
--- a/fs/cifs/smb2pdu.h
+++ b/fs/cifs/smb2pdu.h
@@ -898,7 +898,7 @@ struct validate_negotiate_info_req {
898 __u8 Guid[SMB2_CLIENT_GUID_SIZE]; 898 __u8 Guid[SMB2_CLIENT_GUID_SIZE];
899 __le16 SecurityMode; 899 __le16 SecurityMode;
900 __le16 DialectCount; 900 __le16 DialectCount;
901 __le16 Dialects[3]; /* BB expand this if autonegotiate > 3 dialects */ 901 __le16 Dialects[4]; /* BB expand this if autonegotiate > 4 dialects */
902} __packed; 902} __packed;
903 903
904struct validate_negotiate_info_rsp { 904struct validate_negotiate_info_rsp {