Skip to content

Commit

Permalink
ksmbd: validate mech token in session setup
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
namjaejeon committed Jan 12, 2024
1 parent 2df026a commit ba47560
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 5 deletions.
5 changes: 5 additions & 0 deletions asn1.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,10 +318,15 @@ static int ksmbd_neg_token_alloc(void *context, size_t hdrlen,
{
struct ksmbd_conn *conn = context;

if (!vlen)
return -EINVAL;

conn->mechToken = kmemdup_nul(value, vlen, GFP_KERNEL);
if (!conn->mechToken)
return -ENOMEM;

conn->mechTokenLen = (unsigned int)vlen;

return 0;
}

Expand Down
1 change: 1 addition & 0 deletions connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ struct ksmbd_conn {
__u16 dialect;

char *mechToken;
unsigned int mechTokenLen;

struct ksmbd_conn_ops *conn_ops;

Expand Down
22 changes: 17 additions & 5 deletions smb2pdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1428,7 +1428,10 @@ static struct ksmbd_user *session_user(struct ksmbd_conn *conn,
char *name;
unsigned int name_off, name_len, secbuf_len;

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

authblob = user_authblob(conn, req);
sz = le16_to_cpu(req->SecurityBufferLength);
if (conn->use_spnego && conn->mechToken)
sz = conn->mechTokenLen;
else
sz = le16_to_cpu(req->SecurityBufferLength);
rc = ksmbd_decode_ntlmssp_auth_blob(authblob, sz, conn, sess);
if (rc) {
set_user_flag(sess->user, KSMBD_USER_FLAG_BAD_PASSWORD);
Expand Down Expand Up @@ -1796,8 +1802,7 @@ int smb2_sess_setup(struct ksmbd_work *work)

negblob_off = le16_to_cpu(req->SecurityBufferOffset);
negblob_len = le16_to_cpu(req->SecurityBufferLength);
if (negblob_off < offsetof(struct smb2_sess_setup_req, Buffer) ||
negblob_len < offsetof(struct negotiate_message, NegotiateFlags)) {
if (negblob_off < offsetof(struct smb2_sess_setup_req, Buffer)) {
rc = -EINVAL;
goto out_err;
}
Expand All @@ -1806,8 +1811,15 @@ int smb2_sess_setup(struct ksmbd_work *work)
negblob_off);

if (decode_negotiation_token(conn, negblob, negblob_len) == 0) {
if (conn->mechToken)
if (conn->mechToken) {
negblob = (struct negotiate_message *)conn->mechToken;
negblob_len = conn->mechTokenLen;
}
}

if (negblob_len < offsetof(struct negotiate_message, NegotiateFlags)) {
rc = -EINVAL;
goto out_err;
}

if (server_conf.auth_mechs & conn->auth_mechs) {
Expand Down

0 comments on commit ba47560

Please sign in to comment.