]> git.itanic.dy.fi Git - linux-stable/commitdiff
ksmbd: fix deadlock in ksmbd_find_crypto_ctx()
authorNamjae Jeon <linkinjeon@kernel.org>
Tue, 2 May 2023 23:44:14 +0000 (08:44 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 17 May 2023 09:50:29 +0000 (11:50 +0200)
[ Upstream commit 7b4323373d844954bb76e0e9f39c4e5fc785fa7b ]

Deadlock is triggered by sending multiple concurrent session setup
requests. It should be reused after releasing when getting ctx for crypto.
Multiple consecutive ctx uses cause deadlock while waiting for releasing
due to the limited number of ctx.

Cc: stable@vger.kernel.org
Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-20591
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/ksmbd/auth.c

index c1408e922fc6b4097f5626fd148a5f47c0d1c391..59d20594674651ab1837936ab6ec58ab4f7c02c2 100644 (file)
@@ -220,22 +220,22 @@ int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
 {
        char ntlmv2_hash[CIFS_ENCPWD_SIZE];
        char ntlmv2_rsp[CIFS_HMAC_MD5_HASH_SIZE];
-       struct ksmbd_crypto_ctx *ctx;
+       struct ksmbd_crypto_ctx *ctx = NULL;
        char *construct = NULL;
        int rc, len;
 
-       ctx = ksmbd_crypto_ctx_find_hmacmd5();
-       if (!ctx) {
-               ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
-               return -ENOMEM;
-       }
-
        rc = calc_ntlmv2_hash(conn, sess, ntlmv2_hash, domain_name);
        if (rc) {
                ksmbd_debug(AUTH, "could not get v2 hash rc %d\n", rc);
                goto out;
        }
 
+       ctx = ksmbd_crypto_ctx_find_hmacmd5();
+       if (!ctx) {
+               ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
+               return -ENOMEM;
+       }
+
        rc = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
                                 ntlmv2_hash,
                                 CIFS_HMAC_MD5_HASH_SIZE);
@@ -271,6 +271,8 @@ int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
                ksmbd_debug(AUTH, "Could not generate md5 hash\n");
                goto out;
        }
+       ksmbd_release_crypto_ctx(ctx);
+       ctx = NULL;
 
        rc = ksmbd_gen_sess_key(sess, ntlmv2_hash, ntlmv2_rsp);
        if (rc) {
@@ -281,7 +283,8 @@ int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
        if (memcmp(ntlmv2->ntlmv2_hash, ntlmv2_rsp, CIFS_HMAC_MD5_HASH_SIZE) != 0)
                rc = -EINVAL;
 out:
-       ksmbd_release_crypto_ctx(ctx);
+       if (ctx)
+               ksmbd_release_crypto_ctx(ctx);
        kfree(construct);
        return rc;
 }