]> git.hungrycats.org Git - linux/commitdiff
crypto: acomp - allocate async request context when cloning
authorJérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Sat, 15 Aug 2026 10:09:18 +0000 (10:09 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 14 Sep 2026 11:36:13 +0000 (13:36 +0200)
[ Upstream commit ee440d4fc0d2f15894ab1f64c474a3adbc858880 ]

ACOMP_REQUEST_ON_STACK() reserves only enough storage for the
synchronous fallback. When an async implementation is selected, callers
clone that stack request before retrying, but acomp_request_clone()
currently copies only the stack-sized object. The clone therefore has no
storage for the async provider request context, and providers such as QAT
write past the allocation through acomp_request_ctx(). KASAN does report
a slab OOB write.

Allocate a zeroed clone large enough for the runtime acomp request size,
copy only the bytes present in the source object, and preserve the
existing fallback-on-allocation-failure behavior. Use the runtime reqsize
because an implementation may adjust it during tfm initialization.

Fixes: 097c432caaa6 ("crypto: acomp - Add ACOMP_REQUEST_CLONE")
Assisted-by: Codex:gpt-5
Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Sasha Levin <sashal@kernel.org>
crypto/acompress.c

index 25af7697d6bb96ff397120541f7830fd1d92fb46..aa427b6235a507321807073bcb0e892f7430e8b2 100644 (file)
@@ -567,12 +567,22 @@ EXPORT_SYMBOL_GPL(acomp_walk_virt);
 struct acomp_req *acomp_request_clone(struct acomp_req *req,
                                      size_t total, gfp_t gfp)
 {
+       struct crypto_tfm *tfm = req->base.tfm;
        struct acomp_req *nreq;
+       size_t len;
 
-       nreq = container_of(crypto_request_clone(&req->base, total, gfp),
-                           struct acomp_req, base);
-       if (nreq == req)
+       len = sizeof(*req) +
+             crypto_acomp_reqsize(crypto_acomp_reqtfm(req));
+       len = ALIGN(len, CRYPTO_MINALIGN);
+
+       nreq = kzalloc(len, gfp);
+       if (!nreq) {
+               req->base.tfm = tfm->fb;
                return req;
+       }
+
+       memcpy(nreq, req, sizeof(*req));
+       nreq->base.flags &= ~CRYPTO_TFM_REQ_ON_STACK;
 
        if (req->src == &req->chain.ssg)
                nreq->src = &nreq->chain.ssg;