Skip to content

Commit 8ef1832

Browse files
bugjoshgregkh
authored andcommitted
ksmbd: fix use-after-free from async crypto on Qualcomm crypto engine
[ Upstream commit 3e29889 ] ksmbd_crypt_message() sets a NULL completion callback on AEAD requests and does not handle the -EINPROGRESS return code from async hardware crypto engines like the Qualcomm Crypto Engine (QCE). When QCE returns -EINPROGRESS, ksmbd treats it as an error and immediately frees the request while the hardware DMA operation is still in flight. The DMA completion callback then dereferences freed memory, causing a NULL pointer crash: pc : qce_skcipher_done+0x24/0x174 lr : vchan_complete+0x230/0x27c ... el1h_64_irq+0x68/0x6c ksmbd_free_work_struct+0x20/0x118 [ksmbd] ksmbd_exit_file_cache+0x694/0xa4c [ksmbd] Use the standard crypto_wait_req() pattern with crypto_req_done() as the completion callback, matching the approach used by the SMB client in fs/smb/client/smb2ops.c. This properly handles both synchronous engines (immediate return) and async engines (-EINPROGRESS followed by callback notification). Fixes: e2f3448 ("cifsd: add server-side procedures for SMB3") Link: openwrt/openwrt#21822 Signed-off-by: Joshua Klinesmith <joshuaklinesmith@gmail.com> Acked-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 5e18533 commit 8ef1832

1 file changed

Lines changed: 6 additions & 5 deletions

File tree

fs/smb/server/auth.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,6 +1111,7 @@ int ksmbd_crypt_message(struct ksmbd_work *work, struct kvec *iov,
11111111
struct smb2_transform_hdr *tr_hdr = smb2_get_msg(iov[0].iov_base);
11121112
unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
11131113
int rc;
1114+
DECLARE_CRYPTO_WAIT(wait);
11141115
struct scatterlist *sg;
11151116
u8 sign[SMB2_SIGNATURE_SIZE] = {};
11161117
u8 key[SMB3_ENC_DEC_KEY_SIZE];
@@ -1197,12 +1198,12 @@ int ksmbd_crypt_message(struct ksmbd_work *work, struct kvec *iov,
11971198

11981199
aead_request_set_crypt(req, sg, sg, crypt_len, iv);
11991200
aead_request_set_ad(req, assoc_data_len);
1200-
aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
1201+
aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
1202+
CRYPTO_TFM_REQ_MAY_SLEEP,
1203+
crypto_req_done, &wait);
12011204

1202-
if (enc)
1203-
rc = crypto_aead_encrypt(req);
1204-
else
1205-
rc = crypto_aead_decrypt(req);
1205+
rc = crypto_wait_req(enc ? crypto_aead_encrypt(req) :
1206+
crypto_aead_decrypt(req), &wait);
12061207
if (rc)
12071208
goto free_iv;
12081209

0 commit comments

Comments
 (0)