@@ -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
491487assemble_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 {
0 commit comments