@@ -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
454
#define SMB2_PREAUTH_INTEGRITY_CAPABILITIES cpu_to_le16(1)
459
455
#define SMB2_ENCRYPTION_CAPABILITIES cpu_to_le16(2)
460
456
#define SMB2_POSIX_EXTENSIONS_AVAILABLE cpu_to_le16(0x100)
@@ -491,10 +487,24 @@ static void
491
487
assemble_neg_contexts (struct smb2_negotiate_req * req ,
492
488
unsigned int * total_len )
493
489
{
494
- char * pneg_ctxt = (char * )req + OFFSET_OF_NEG_CONTEXT ;
490
+ char * pneg_ctxt = (char * )req ;
495
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
508
build_preauth_ctxt ((struct smb2_preauth_neg_context * )pneg_ctxt );
499
509
ctxt_len = DIV_ROUND_UP (sizeof (struct smb2_preauth_neg_context ), 8 ) * 8 ;
500
510
* total_len += ctxt_len ;
@@ -508,7 +518,6 @@ assemble_neg_contexts(struct smb2_negotiate_req *req,
508
518
build_posix_ctxt ((struct smb2_posix_neg_context * )pneg_ctxt );
509
519
* total_len += sizeof (struct smb2_posix_neg_context );
510
520
511
- req -> NegotiateContextOffset = cpu_to_le32 (OFFSET_OF_NEG_CONTEXT );
512
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
733
req -> Dialects [0 ] = cpu_to_le16 (SMB21_PROT_ID );
725
734
req -> Dialects [1 ] = cpu_to_le16 (SMB30_PROT_ID );
726
735
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 ;
729
739
} else {
730
740
/* otherwise send specific dialect */
731
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
759
else {
750
760
memcpy (req -> ClientGUID , server -> client_guid ,
751
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
765
assemble_neg_contexts (req , & total_len );
754
766
}
755
767
iov [0 ].iov_base = (char * )req ;
@@ -794,7 +806,8 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
794
806
} else if (rsp -> DialectRevision == cpu_to_le16 (SMB21_PROT_ID )) {
795
807
/* ops set to 3.0 by default for default so update */
796
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
811
} else if (le16_to_cpu (rsp -> DialectRevision ) !=
799
812
ses -> server -> vals -> protocol_id ) {
800
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
954
pneg_inbuf -> DialectCount = cpu_to_le16 (2 );
942
955
/* structure is big enough for 3 dialects, sending only 2 */
943
956
inbuflen = sizeof (* pneg_inbuf ) -
944
- sizeof (pneg_inbuf -> Dialects [0 ]);
957
+ ( 2 * sizeof (pneg_inbuf -> Dialects [0 ]) );
945
958
} else if (strcmp (tcon -> ses -> server -> vals -> version_string ,
946
959
SMBDEFAULT_VERSION_STRING ) == 0 ) {
947
960
pneg_inbuf -> Dialects [0 ] = cpu_to_le16 (SMB21_PROT_ID );
948
961
pneg_inbuf -> Dialects [1 ] = cpu_to_le16 (SMB30_PROT_ID );
949
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
965
/* structure is big enough for 3 dialects */
952
966
inbuflen = sizeof (* pneg_inbuf );
953
967
} else {
0 commit comments