@@ -587,11 +587,15 @@ assemble_neg_contexts(struct smb2_negotiate_req *req,
587587
588588}
589589
590+ /* If invalid preauth context warn but use what we requested, SHA-512 */
590591static void decode_preauth_context (struct smb2_preauth_neg_context * ctxt )
591592{
592593 unsigned int len = le16_to_cpu (ctxt -> DataLength );
593594
594- /* If invalid preauth context warn but use what we requested, SHA-512 */
595+ /*
596+ * Caller checked that DataLength remains within SMB boundary. We still
597+ * need to confirm that one HashAlgorithms member is accounted for.
598+ */
595599 if (len < MIN_PREAUTH_CTXT_DATA_LEN ) {
596600 pr_warn_once ("server sent bad preauth context\n" );
597601 return ;
@@ -610,7 +614,11 @@ static void decode_compress_ctx(struct TCP_Server_Info *server,
610614{
611615 unsigned int len = le16_to_cpu (ctxt -> DataLength );
612616
613- /* sizeof compress context is a one element compression capbility struct */
617+ /*
618+ * Caller checked that DataLength remains within SMB boundary. We still
619+ * need to confirm that one CompressionAlgorithms member is accounted
620+ * for.
621+ */
614622 if (len < 10 ) {
615623 pr_warn_once ("server sent bad compression cntxt\n" );
616624 return ;
@@ -632,6 +640,11 @@ static int decode_encrypt_ctx(struct TCP_Server_Info *server,
632640 unsigned int len = le16_to_cpu (ctxt -> DataLength );
633641
634642 cifs_dbg (FYI , "decode SMB3.11 encryption neg context of len %d\n" , len );
643+ /*
644+ * Caller checked that DataLength remains within SMB boundary. We still
645+ * need to confirm that one Cipher flexible array member is accounted
646+ * for.
647+ */
635648 if (len < MIN_ENCRYPT_CTXT_DATA_LEN ) {
636649 pr_warn_once ("server sent bad crypto ctxt len\n" );
637650 return - EINVAL ;
@@ -678,6 +691,11 @@ static void decode_signing_ctx(struct TCP_Server_Info *server,
678691{
679692 unsigned int len = le16_to_cpu (pctxt -> DataLength );
680693
694+ /*
695+ * Caller checked that DataLength remains within SMB boundary. We still
696+ * need to confirm that one SigningAlgorithms flexible array member is
697+ * accounted for.
698+ */
681699 if ((len < 4 ) || (len > 16 )) {
682700 pr_warn_once ("server sent bad signing negcontext\n" );
683701 return ;
@@ -719,14 +737,19 @@ static int smb311_decode_neg_context(struct smb2_negotiate_rsp *rsp,
719737 for (i = 0 ; i < ctxt_cnt ; i ++ ) {
720738 int clen ;
721739 /* check that offset is not beyond end of SMB */
722- if (len_of_ctxts == 0 )
723- break ;
724-
725740 if (len_of_ctxts < sizeof (struct smb2_neg_context ))
726741 break ;
727742
728743 pctx = (struct smb2_neg_context * )(offset + (char * )rsp );
729- clen = le16_to_cpu (pctx -> DataLength );
744+ clen = sizeof (struct smb2_neg_context )
745+ + le16_to_cpu (pctx -> DataLength );
746+ /*
747+ * 2.2.4 SMB2 NEGOTIATE Response
748+ * Subsequent negotiate contexts MUST appear at the first 8-byte
749+ * aligned offset following the previous negotiate context.
750+ */
751+ if (i + 1 != ctxt_cnt )
752+ clen = ALIGN (clen , 8 );
730753 if (clen > len_of_ctxts )
731754 break ;
732755
@@ -747,12 +770,10 @@ static int smb311_decode_neg_context(struct smb2_negotiate_rsp *rsp,
747770 else
748771 cifs_server_dbg (VFS , "unknown negcontext of type %d ignored\n" ,
749772 le16_to_cpu (pctx -> ContextType ));
750-
751773 if (rc )
752774 break ;
753- /* offsets must be 8 byte aligned */
754- clen = ALIGN (clen , 8 );
755- offset += clen + sizeof (struct smb2_neg_context );
775+
776+ offset += clen ;
756777 len_of_ctxts -= clen ;
757778 }
758779 return rc ;
0 commit comments