Skip to content

Commit ba47560

Browse files
committed
ksmbd: validate mech token in session setup
If client send invalid mech token in session setup request, ksmbd validate and make the error if it is invalid. Reported-by: [email protected] # ZDI-CAN-22890 Cc: [email protected] Signed-off-by: Namjae Jeon <[email protected]>
1 parent 2df026a commit ba47560

File tree

3 files changed

+23
-5
lines changed

3 files changed

+23
-5
lines changed

asn1.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,10 +318,15 @@ static int ksmbd_neg_token_alloc(void *context, size_t hdrlen,
318318
{
319319
struct ksmbd_conn *conn = context;
320320

321+
if (!vlen)
322+
return -EINVAL;
323+
321324
conn->mechToken = kmemdup_nul(value, vlen, GFP_KERNEL);
322325
if (!conn->mechToken)
323326
return -ENOMEM;
324327

328+
conn->mechTokenLen = (unsigned int)vlen;
329+
325330
return 0;
326331
}
327332

connection.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ struct ksmbd_conn {
8888
__u16 dialect;
8989

9090
char *mechToken;
91+
unsigned int mechTokenLen;
9192

9293
struct ksmbd_conn_ops *conn_ops;
9394

smb2pdu.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1428,7 +1428,10 @@ static struct ksmbd_user *session_user(struct ksmbd_conn *conn,
14281428
char *name;
14291429
unsigned int name_off, name_len, secbuf_len;
14301430

1431-
secbuf_len = le16_to_cpu(req->SecurityBufferLength);
1431+
if (conn->use_spnego && conn->mechToken)
1432+
secbuf_len = conn->mechTokenLen;
1433+
else
1434+
secbuf_len = le16_to_cpu(req->SecurityBufferLength);
14321435
if (secbuf_len < sizeof(struct authenticate_message)) {
14331436
ksmbd_debug(SMB, "blob len %d too small\n", secbuf_len);
14341437
return NULL;
@@ -1519,7 +1522,10 @@ static int ntlm_authenticate(struct ksmbd_work *work,
15191522
struct authenticate_message *authblob;
15201523

15211524
authblob = user_authblob(conn, req);
1522-
sz = le16_to_cpu(req->SecurityBufferLength);
1525+
if (conn->use_spnego && conn->mechToken)
1526+
sz = conn->mechTokenLen;
1527+
else
1528+
sz = le16_to_cpu(req->SecurityBufferLength);
15231529
rc = ksmbd_decode_ntlmssp_auth_blob(authblob, sz, conn, sess);
15241530
if (rc) {
15251531
set_user_flag(sess->user, KSMBD_USER_FLAG_BAD_PASSWORD);
@@ -1796,8 +1802,7 @@ int smb2_sess_setup(struct ksmbd_work *work)
17961802

17971803
negblob_off = le16_to_cpu(req->SecurityBufferOffset);
17981804
negblob_len = le16_to_cpu(req->SecurityBufferLength);
1799-
if (negblob_off < offsetof(struct smb2_sess_setup_req, Buffer) ||
1800-
negblob_len < offsetof(struct negotiate_message, NegotiateFlags)) {
1805+
if (negblob_off < offsetof(struct smb2_sess_setup_req, Buffer)) {
18011806
rc = -EINVAL;
18021807
goto out_err;
18031808
}
@@ -1806,8 +1811,15 @@ int smb2_sess_setup(struct ksmbd_work *work)
18061811
negblob_off);
18071812

18081813
if (decode_negotiation_token(conn, negblob, negblob_len) == 0) {
1809-
if (conn->mechToken)
1814+
if (conn->mechToken) {
18101815
negblob = (struct negotiate_message *)conn->mechToken;
1816+
negblob_len = conn->mechTokenLen;
1817+
}
1818+
}
1819+
1820+
if (negblob_len < offsetof(struct negotiate_message, NegotiateFlags)) {
1821+
rc = -EINVAL;
1822+
goto out_err;
18111823
}
18121824

18131825
if (server_conf.auth_mechs & conn->auth_mechs) {

0 commit comments

Comments
 (0)