@@ -1257,19 +1257,13 @@ static int generate_preauth_hash(struct ksmbd_work *work)
1257
1257
return 0 ;
1258
1258
}
1259
1259
1260
- static int decode_negotiation_token (struct ksmbd_work * work ,
1261
- struct negotiate_message * negblob )
1260
+ static int decode_negotiation_token (struct ksmbd_conn * conn ,
1261
+ struct negotiate_message * negblob ,
1262
+ size_t sz )
1262
1263
{
1263
- struct ksmbd_conn * conn = work -> conn ;
1264
- struct smb2_sess_setup_req * req ;
1265
- int sz ;
1266
-
1267
1264
if (!conn -> use_spnego )
1268
1265
return - EINVAL ;
1269
1266
1270
- req = work -> request_buf ;
1271
- sz = le16_to_cpu (req -> SecurityBufferLength );
1272
-
1273
1267
if (ksmbd_decode_negTokenInit ((char * )negblob , sz , conn )) {
1274
1268
if (ksmbd_decode_negTokenTarg ((char * )negblob , sz , conn )) {
1275
1269
conn -> auth_mechs |= KSMBD_AUTH_NTLMSSP ;
@@ -1281,9 +1275,9 @@ static int decode_negotiation_token(struct ksmbd_work *work,
1281
1275
}
1282
1276
1283
1277
static int ntlm_negotiate (struct ksmbd_work * work ,
1284
- struct negotiate_message * negblob )
1278
+ struct negotiate_message * negblob ,
1279
+ size_t negblob_len )
1285
1280
{
1286
- struct smb2_sess_setup_req * req = work -> request_buf ;
1287
1281
struct smb2_sess_setup_rsp * rsp = work -> response_buf ;
1288
1282
struct challenge_message * chgblob ;
1289
1283
unsigned char * spnego_blob = NULL ;
@@ -1292,8 +1286,7 @@ static int ntlm_negotiate(struct ksmbd_work *work,
1292
1286
int sz , rc ;
1293
1287
1294
1288
ksmbd_debug (SMB , "negotiate phase\n" );
1295
- sz = le16_to_cpu (req -> SecurityBufferLength );
1296
- rc = ksmbd_decode_ntlmssp_neg_blob (negblob , sz , work -> sess );
1289
+ rc = ksmbd_decode_ntlmssp_neg_blob (negblob , negblob_len , work -> sess );
1297
1290
if (rc )
1298
1291
return rc ;
1299
1292
@@ -1361,12 +1354,23 @@ static struct ksmbd_user *session_user(struct ksmbd_conn *conn,
1361
1354
struct authenticate_message * authblob ;
1362
1355
struct ksmbd_user * user ;
1363
1356
char * name ;
1364
- int sz ;
1357
+ unsigned int auth_msg_len , name_off , name_len , secbuf_len ;
1365
1358
1359
+ secbuf_len = le16_to_cpu (req -> SecurityBufferLength );
1360
+ if (secbuf_len < sizeof (struct authenticate_message )) {
1361
+ ksmbd_debug (SMB , "blob len %d too small\n" , secbuf_len );
1362
+ return NULL ;
1363
+ }
1366
1364
authblob = user_authblob (conn , req );
1367
- sz = le32_to_cpu (authblob -> UserName .BufferOffset );
1368
- name = smb_strndup_from_utf16 ((const char * )authblob + sz ,
1369
- le16_to_cpu (authblob -> UserName .Length ),
1365
+ name_off = le32_to_cpu (authblob -> UserName .BufferOffset );
1366
+ name_len = le16_to_cpu (authblob -> UserName .Length );
1367
+ auth_msg_len = le16_to_cpu (req -> SecurityBufferOffset ) + secbuf_len ;
1368
+
1369
+ if (auth_msg_len < (u64 )name_off + name_len )
1370
+ return NULL ;
1371
+
1372
+ name = smb_strndup_from_utf16 ((const char * )authblob + name_off ,
1373
+ name_len ,
1370
1374
true,
1371
1375
conn -> local_nls );
1372
1376
if (IS_ERR (name )) {
@@ -1612,6 +1616,7 @@ int smb2_sess_setup(struct ksmbd_work *work)
1612
1616
struct smb2_sess_setup_rsp * rsp = work -> response_buf ;
1613
1617
struct ksmbd_session * sess ;
1614
1618
struct negotiate_message * negblob ;
1619
+ unsigned int negblob_len , negblob_off ;
1615
1620
int rc = 0 ;
1616
1621
1617
1622
ksmbd_debug (SMB , "Received request for session setup\n" );
@@ -1692,10 +1697,16 @@ int smb2_sess_setup(struct ksmbd_work *work)
1692
1697
if (sess -> state == SMB2_SESSION_EXPIRED )
1693
1698
sess -> state = SMB2_SESSION_IN_PROGRESS ;
1694
1699
1700
+ negblob_off = le16_to_cpu (req -> SecurityBufferOffset );
1701
+ negblob_len = le16_to_cpu (req -> SecurityBufferLength );
1702
+ if (negblob_off < (offsetof(struct smb2_sess_setup_req , Buffer ) - 4 ) ||
1703
+ negblob_len < offsetof(struct negotiate_message , NegotiateFlags ))
1704
+ return - EINVAL ;
1705
+
1695
1706
negblob = (struct negotiate_message * )((char * )& req -> hdr .ProtocolId +
1696
- le16_to_cpu ( req -> SecurityBufferOffset ) );
1707
+ negblob_off );
1697
1708
1698
- if (decode_negotiation_token (work , negblob ) == 0 ) {
1709
+ if (decode_negotiation_token (conn , negblob , negblob_len ) == 0 ) {
1699
1710
if (conn -> mechToken )
1700
1711
negblob = (struct negotiate_message * )conn -> mechToken ;
1701
1712
}
@@ -1719,7 +1730,7 @@ int smb2_sess_setup(struct ksmbd_work *work)
1719
1730
sess -> Preauth_HashValue = NULL ;
1720
1731
} else if (conn -> preferred_auth_mech == KSMBD_AUTH_NTLMSSP ) {
1721
1732
if (negblob -> MessageType == NtLmNegotiate ) {
1722
- rc = ntlm_negotiate (work , negblob );
1733
+ rc = ntlm_negotiate (work , negblob , negblob_len );
1723
1734
if (rc )
1724
1735
goto out_err ;
1725
1736
rsp -> hdr .Status =
0 commit comments