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.

Cc: stable@vger.kernel.org
Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-22890
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
  • Loading branch information
namjaejeon authored and Steve French committed Jan 14, 2024
1 parent fdfd6dd commit 92e4701
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 5 deletions.
5 changes: 5 additions & 0 deletions fs/smb/server/asn1.c
Expand Up @@ -214,10 +214,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 fs/smb/server/connection.h
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 fs/smb/server/smb2pdu.c
Expand Up @@ -1414,7 +1414,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 @@ -1505,7 +1508,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 @@ -1778,8 +1784,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 @@ -1788,8 +1793,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 92e4701

Please sign in to comment.