diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-01-05 17:05:06 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-01-05 17:05:06 -0500 |
commit | 7e928df80d30b7664b5822784c95b4a54dc7cfbf (patch) | |
tree | 6926184cd629693315c0061bce310db4b9de6165 | |
parent | 3cd6d495db2a0acfd2854f43aac8bfc5914bc89c (diff) | |
parent | d5c7076b772ad7dcdb92303397b36aee8fa0d25d (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.c | 2 | ||||
-rw-r--r-- | fs/cifs/smb2ops.c | 4 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.c | 40 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.h | 2 |
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 | |||
491 | assemble_neg_contexts(struct smb2_negotiate_req *req, | 487 | assemble_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 | ||
904 | struct validate_negotiate_info_rsp { | 904 | struct validate_negotiate_info_rsp { |