From cfb32c656eb7bf1d7a776b8793bb6baa6f58b5a4 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 8 Apr 2025 12:20:34 +0800 Subject: [PATCH 1/2] crypto: scomp - Fix null-pointer deref when freeing streams As the scomp streams are freed when an algorithm is unregistered, it is possible that the algorithm has never been used at all (e.g., an algorithm that does not have a self-test). So test whether the streams exist before freeing them. Reported-by: Sourabh Jain Fixes: 3d72ad46a23a ("crypto: acomp - Move stream management into scomp layer") Signed-off-by: Herbert Xu Tested-by: Sourabh Jain Signed-off-by: Herbert Xu --- crypto/scompress.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crypto/scompress.c b/crypto/scompress.c index d435d4b24469..f67ce38d203d 100644 --- a/crypto/scompress.c +++ b/crypto/scompress.c @@ -111,6 +111,9 @@ static void scomp_free_streams(struct scomp_alg *alg) struct crypto_acomp_stream __percpu *stream = alg->stream; int i; + if (!stream) + return; + for_each_possible_cpu(i) { struct crypto_acomp_stream *ps = per_cpu_ptr(stream, i); From b7b39df7e710b0068356e4c696af07aa10e2cd3d Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 8 Apr 2025 13:17:20 +0800 Subject: [PATCH 2/2] crypto: caam/qi - Fix drv_ctx refcount bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensure refcount is raised before request is enqueued since it could be dequeued before the call returns. Reported-by: Sean Anderson Cc: Fixes: 11144416a755 ("crypto: caam/qi - optimize frame queue cleanup") Signed-off-by: Herbert Xu Reviewed-by: Horia Geantă Tested-by: Sean Anderson Signed-off-by: Herbert Xu --- drivers/crypto/caam/qi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/crypto/caam/qi.c b/drivers/crypto/caam/qi.c index 7701d00bcb3a..b6e7c0b29d4e 100644 --- a/drivers/crypto/caam/qi.c +++ b/drivers/crypto/caam/qi.c @@ -122,12 +122,12 @@ int caam_qi_enqueue(struct device *qidev, struct caam_drv_req *req) qm_fd_addr_set64(&fd, addr); do { + refcount_inc(&req->drv_ctx->refcnt); ret = qman_enqueue(req->drv_ctx->req_fq, &fd); - if (likely(!ret)) { - refcount_inc(&req->drv_ctx->refcnt); + if (likely(!ret)) return 0; - } + refcount_dec(&req->drv_ctx->refcnt); if (ret != -EBUSY) break; num_retries++;