Commit 92e47016 authored by Namjae Jeon's avatar Namjae Jeon Committed by Steve French
Browse files

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.

Cc: stable@vger.kernel.org
Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-22890
Signed-off-by: default avatarNamjae Jeon <linkinjeon@kernel.org>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent fdfd6dde
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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;
}

+1 −0
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ struct ksmbd_conn {
	__u16				dialect;

	char				*mechToken;
	unsigned int			mechTokenLen;

	struct ksmbd_conn_ops	*conn_ops;

+17 −5
Original line number Diff line number Diff line
@@ -1414,6 +1414,9 @@ static struct ksmbd_user *session_user(struct ksmbd_conn *conn,
	char *name;
	unsigned int name_off, name_len, secbuf_len;

	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);
@@ -1505,6 +1508,9 @@ static int ntlm_authenticate(struct ksmbd_work *work,
		struct authenticate_message *authblob;

		authblob = user_authblob(conn, req);
		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) {
@@ -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;
	}
@@ -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) {