[SRU][Q][PATCH 1/1] ksmbd: fix use-after-free from async crypto on Qualcomm crypto engine
Cengiz Can
cengiz.can at canonical.com
Thu Jul 16 22:57:59 UTC 2026
From: Joshua Klinesmith <joshuaklinesmith at gmail.com>
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: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
Link: https://github.com/openwrt/openwrt/issues/21822
Signed-off-by: Joshua Klinesmith <joshuaklinesmith at gmail.com>
Acked-by: Namjae Jeon <linkinjeon at kernel.org>
Signed-off-by: Steve French <stfrench at microsoft.com>
(cherry picked from commit 3e298897f41c61450c2e7a4f457e8b2485eb35b3)
CVE-2026-53046
Assisted-by: kybele:claude-opus-4.8
Signed-off-by: Cengiz Can <cengiz.can at canonical.com>
---
fs/smb/server/auth.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/fs/smb/server/auth.c b/fs/smb/server/auth.c
index d99871c21451..b5b63e8e7292 100644
--- a/fs/smb/server/auth.c
+++ b/fs/smb/server/auth.c
@@ -1093,6 +1093,7 @@ int ksmbd_crypt_message(struct ksmbd_work *work, struct kvec *iov,
struct smb2_transform_hdr *tr_hdr = smb2_get_msg(iov[0].iov_base);
unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
int rc;
+ DECLARE_CRYPTO_WAIT(wait);
struct scatterlist *sg;
u8 sign[SMB2_SIGNATURE_SIZE] = {};
u8 key[SMB3_ENC_DEC_KEY_SIZE];
@@ -1179,12 +1180,12 @@ int ksmbd_crypt_message(struct ksmbd_work *work, struct kvec *iov,
aead_request_set_crypt(req, sg, sg, crypt_len, iv);
aead_request_set_ad(req, assoc_data_len);
- aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
+ aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
+ CRYPTO_TFM_REQ_MAY_SLEEP,
+ crypto_req_done, &wait);
- if (enc)
- rc = crypto_aead_encrypt(req);
- else
- rc = crypto_aead_decrypt(req);
+ rc = crypto_wait_req(enc ? crypto_aead_encrypt(req) :
+ crypto_aead_decrypt(req), &wait);
if (rc)
goto free_iv;
--
2.43.0
More information about the kernel-team
mailing list