Skip to content

Commit d5c7076

Browse files
author
Steve French
committed
smb3: add smb3.1.1 to default dialect list
SMB3.1.1 dialect has additional security (among other) features and should be requested when mounting to modern servers so it can be used if the server supports it. Add SMB3.1.1 to the default list of dialects requested. Signed-off-by: Steve French <[email protected]> Reviewed-by: Ronnie Sahlberg <[email protected]>
1 parent 55a7f00 commit d5c7076

File tree

2 files changed

+28
-14
lines changed

2 files changed

+28
-14
lines changed

fs/cifs/smb2pdu.c

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -451,10 +451,6 @@ smb2_plain_req_init(__le16 smb2_command, struct cifs_tcon *tcon,
451451
}
452452

453453

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-
458454
#define SMB2_PREAUTH_INTEGRITY_CAPABILITIES cpu_to_le16(1)
459455
#define SMB2_ENCRYPTION_CAPABILITIES cpu_to_le16(2)
460456
#define SMB2_POSIX_EXTENSIONS_AVAILABLE cpu_to_le16(0x100)
@@ -491,10 +487,24 @@ static void
491487
assemble_neg_contexts(struct smb2_negotiate_req *req,
492488
unsigned int *total_len)
493489
{
494-
char *pneg_ctxt = (char *)req + OFFSET_OF_NEG_CONTEXT;
490+
char *pneg_ctxt = (char *)req;
495491
unsigned int ctxt_len;
496492

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+
498508
build_preauth_ctxt((struct smb2_preauth_neg_context *)pneg_ctxt);
499509
ctxt_len = DIV_ROUND_UP(sizeof(struct smb2_preauth_neg_context), 8) * 8;
500510
*total_len += ctxt_len;
@@ -508,7 +518,6 @@ assemble_neg_contexts(struct smb2_negotiate_req *req,
508518
build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt);
509519
*total_len += sizeof(struct smb2_posix_neg_context);
510520

511-
req->NegotiateContextOffset = cpu_to_le32(OFFSET_OF_NEG_CONTEXT);
512521
req->NegotiateContextCount = cpu_to_le16(3);
513522
}
514523

@@ -724,8 +733,9 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
724733
req->Dialects[0] = cpu_to_le16(SMB21_PROT_ID);
725734
req->Dialects[1] = cpu_to_le16(SMB30_PROT_ID);
726735
req->Dialects[2] = cpu_to_le16(SMB302_PROT_ID);
727-
req->DialectCount = cpu_to_le16(3);
728-
total_len += 6;
736+
req->Dialects[3] = cpu_to_le16(SMB311_PROT_ID);
737+
req->DialectCount = cpu_to_le16(4);
738+
total_len += 8;
729739
} else {
730740
/* otherwise send specific dialect */
731741
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)
749759
else {
750760
memcpy(req->ClientGUID, server->client_guid,
751761
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))
753765
assemble_neg_contexts(req, &total_len);
754766
}
755767
iov[0].iov_base = (char *)req;
@@ -794,7 +806,8 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
794806
} else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) {
795807
/* ops set to 3.0 by default for default so update */
796808
ses->server->ops = &smb21_operations;
797-
}
809+
} else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID))
810+
ses->server->ops = &smb311_operations;
798811
} else if (le16_to_cpu(rsp->DialectRevision) !=
799812
ses->server->vals->protocol_id) {
800813
/* if requested single dialect ensure returned dialect matched */
@@ -941,13 +954,14 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
941954
pneg_inbuf->DialectCount = cpu_to_le16(2);
942955
/* structure is big enough for 3 dialects, sending only 2 */
943956
inbuflen = sizeof(*pneg_inbuf) -
944-
sizeof(pneg_inbuf->Dialects[0]);
957+
(2 * sizeof(pneg_inbuf->Dialects[0]));
945958
} else if (strcmp(tcon->ses->server->vals->version_string,
946959
SMBDEFAULT_VERSION_STRING) == 0) {
947960
pneg_inbuf->Dialects[0] = cpu_to_le16(SMB21_PROT_ID);
948961
pneg_inbuf->Dialects[1] = cpu_to_le16(SMB30_PROT_ID);
949962
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);
951965
/* structure is big enough for 3 dialects */
952966
inbuflen = sizeof(*pneg_inbuf);
953967
} else {

fs/cifs/smb2pdu.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -898,7 +898,7 @@ struct validate_negotiate_info_req {
898898
__u8 Guid[SMB2_CLIENT_GUID_SIZE];
899899
__le16 SecurityMode;
900900
__le16 DialectCount;
901-
__le16 Dialects[3]; /* BB expand this if autonegotiate > 3 dialects */
901+
__le16 Dialects[4]; /* BB expand this if autonegotiate > 4 dialects */
902902
} __packed;
903903

904904
struct validate_negotiate_info_rsp {

0 commit comments

Comments
 (0)