@@ -845,13 +845,14 @@ static void assemble_neg_contexts(struct ksmbd_conn *conn,
845
845
846
846
static __le32 decode_preauth_ctxt (struct ksmbd_conn * conn ,
847
847
struct smb2_preauth_neg_context * pneg_ctxt ,
848
- int len_of_ctxts )
848
+ int ctxt_len )
849
849
{
850
850
/*
851
851
* sizeof(smb2_preauth_neg_context) assumes SMB311_SALT_SIZE Salt,
852
852
* which may not be present. Only check for used HashAlgorithms[1].
853
853
*/
854
- if (len_of_ctxts < MIN_PREAUTH_CTXT_DATA_LEN )
854
+ if (ctxt_len <
855
+ sizeof (struct smb2_neg_context ) + MIN_PREAUTH_CTXT_DATA_LEN )
855
856
return STATUS_INVALID_PARAMETER ;
856
857
857
858
if (pneg_ctxt -> HashAlgorithms != SMB2_PREAUTH_INTEGRITY_SHA512 )
@@ -863,15 +864,23 @@ static __le32 decode_preauth_ctxt(struct ksmbd_conn *conn,
863
864
864
865
static void decode_encrypt_ctxt (struct ksmbd_conn * conn ,
865
866
struct smb2_encryption_neg_context * pneg_ctxt ,
866
- int len_of_ctxts )
867
+ int ctxt_len )
867
868
{
868
- int cph_cnt = le16_to_cpu (pneg_ctxt -> CipherCount );
869
- int i , cphs_size = cph_cnt * sizeof (__le16 );
869
+ int cph_cnt ;
870
+ int i , cphs_size ;
871
+
872
+ if (sizeof (struct smb2_encryption_neg_context ) > ctxt_len ) {
873
+ pr_err ("Invalid SMB2_ENCRYPTION_CAPABILITIES context size\n" );
874
+ return ;
875
+ }
870
876
871
877
conn -> cipher_type = 0 ;
872
878
879
+ cph_cnt = le16_to_cpu (pneg_ctxt -> CipherCount );
880
+ cphs_size = cph_cnt * sizeof (__le16 );
881
+
873
882
if (sizeof (struct smb2_encryption_neg_context ) + cphs_size >
874
- len_of_ctxts ) {
883
+ ctxt_len ) {
875
884
pr_err ("Invalid cipher count(%d)\n" , cph_cnt );
876
885
return ;
877
886
}
@@ -919,15 +928,22 @@ static void decode_compress_ctxt(struct ksmbd_conn *conn,
919
928
920
929
static void decode_sign_cap_ctxt (struct ksmbd_conn * conn ,
921
930
struct smb2_signing_capabilities * pneg_ctxt ,
922
- int len_of_ctxts )
931
+ int ctxt_len )
923
932
{
924
- int sign_algo_cnt = le16_to_cpu (pneg_ctxt -> SigningAlgorithmCount );
925
- int i , sign_alos_size = sign_algo_cnt * sizeof (__le16 );
933
+ int sign_algo_cnt ;
934
+ int i , sign_alos_size ;
935
+
936
+ if (sizeof (struct smb2_signing_capabilities ) > ctxt_len ) {
937
+ pr_err ("Invalid SMB2_SIGNING_CAPABILITIES context length\n" );
938
+ return ;
939
+ }
926
940
927
941
conn -> signing_negotiated = false;
942
+ sign_algo_cnt = le16_to_cpu (pneg_ctxt -> SigningAlgorithmCount );
943
+ sign_alos_size = sign_algo_cnt * sizeof (__le16 );
928
944
929
945
if (sizeof (struct smb2_signing_capabilities ) + sign_alos_size >
930
- len_of_ctxts ) {
946
+ ctxt_len ) {
931
947
pr_err ("Invalid signing algorithm count(%d)\n" , sign_algo_cnt );
932
948
return ;
933
949
}
@@ -965,18 +981,16 @@ static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn,
965
981
len_of_ctxts = len_of_smb - offset ;
966
982
967
983
while (i ++ < neg_ctxt_cnt ) {
968
- int clen ;
969
-
970
- /* check that offset is not beyond end of SMB */
971
- if (len_of_ctxts == 0 )
972
- break ;
984
+ int clen , ctxt_len ;
973
985
974
986
if (len_of_ctxts < sizeof (struct smb2_neg_context ))
975
987
break ;
976
988
977
989
pctx = (struct smb2_neg_context * )((char * )pctx + offset );
978
990
clen = le16_to_cpu (pctx -> DataLength );
979
- if (clen + sizeof (struct smb2_neg_context ) > len_of_ctxts )
991
+ ctxt_len = clen + sizeof (struct smb2_neg_context );
992
+
993
+ if (ctxt_len > len_of_ctxts )
980
994
break ;
981
995
982
996
if (pctx -> ContextType == SMB2_PREAUTH_INTEGRITY_CAPABILITIES ) {
@@ -987,7 +1001,7 @@ static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn,
987
1001
988
1002
status = decode_preauth_ctxt (conn ,
989
1003
(struct smb2_preauth_neg_context * )pctx ,
990
- len_of_ctxts );
1004
+ ctxt_len );
991
1005
if (status != STATUS_SUCCESS )
992
1006
break ;
993
1007
} else if (pctx -> ContextType == SMB2_ENCRYPTION_CAPABILITIES ) {
@@ -998,7 +1012,7 @@ static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn,
998
1012
999
1013
decode_encrypt_ctxt (conn ,
1000
1014
(struct smb2_encryption_neg_context * )pctx ,
1001
- len_of_ctxts );
1015
+ ctxt_len );
1002
1016
} else if (pctx -> ContextType == SMB2_COMPRESSION_CAPABILITIES ) {
1003
1017
ksmbd_debug (SMB ,
1004
1018
"deassemble SMB2_COMPRESSION_CAPABILITIES context\n" );
@@ -1017,9 +1031,10 @@ static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn,
1017
1031
} else if (pctx -> ContextType == SMB2_SIGNING_CAPABILITIES ) {
1018
1032
ksmbd_debug (SMB ,
1019
1033
"deassemble SMB2_SIGNING_CAPABILITIES context\n" );
1034
+
1020
1035
decode_sign_cap_ctxt (conn ,
1021
1036
(struct smb2_signing_capabilities * )pctx ,
1022
- len_of_ctxts );
1037
+ ctxt_len );
1023
1038
}
1024
1039
1025
1040
/* offsets must be 8 byte aligned */
0 commit comments