@@ -310,6 +310,20 @@ static inline void *acomp_request_extra(struct acomp_req *req)
return (void *)((char *)req + len);
}
+static inline void acomp_request_chain(struct acomp_req *req,
+ struct acomp_req *head)
+{
+ crypto_request_chain(&req->base, &head->base);
+}
+
+static inline void acomp_request_unchain(struct acomp_req *req)
+{
+ crypto_request_unchain(&req->base);
+}
+
+#define acomp_request_for_each(this, tmp, head) \
+ list_for_each_entry_safe((this), (tmp), &(head)->base.list, base.list)
+
/**
* acomp_request_free() -- zeroize and free asynchronous (de)compression
* request as well as the output buffer if allocated
@@ -319,8 +333,16 @@ static inline void *acomp_request_extra(struct acomp_req *req)
*/
static inline void acomp_request_free(struct acomp_req *req)
{
+ struct acomp_req *this, *tmp;
+
if (!req || (req->base.flags & CRYPTO_TFM_REQ_ON_STACK))
return;
+
+ acomp_request_for_each(this, tmp, req) {
+ acomp_request_unchain(this);
+ kfree_sensitive(this);
+ }
+
kfree_sensitive(req);
}
@@ -558,12 +580,6 @@ static inline void acomp_request_set_dst_folio(struct acomp_req *req,
req->base.flags |= CRYPTO_ACOMP_REQ_DST_FOLIO;
}
-static inline void acomp_request_chain(struct acomp_req *req,
- struct acomp_req *head)
-{
- crypto_request_chain(&req->base, &head->base);
-}
-
/**
* crypto_acomp_compress() -- Invoke asynchronous compress operation
*
@@ -486,6 +486,11 @@ static inline void crypto_request_chain(struct crypto_async_request *req,
list_add_tail(&req->list, &head->list);
}
+static inline void crypto_request_unchain(struct crypto_async_request *req)
+{
+ list_del(&req->list);
+}
+
static inline bool crypto_tfm_is_async(struct crypto_tfm *tfm)
{
return tfm->__crt_alg->cra_flags & CRYPTO_ALG_ASYNC;
Running 6.15.0-rc2 with kmemleak enabled, I've noticed 45 memory leaks looks like the following: unreferenced object 0xffff888114032a00 (size 256): comm "cryptomgr_test", pid 246, jiffies 4294668840 hex dump (first 32 bytes): 00 20 03 14 81 88 ff ff 00 da 02 14 81 88 ff ff . .............. 90 ca 54 9b ff ff ff ff c8 fb a6 00 00 c9 ff ff ..T............. backtrace (crc cd58738d): __kmalloc_noprof+0x272/0x520 alg_test_comp+0x74e/0x1b60 alg_test+0x3f0/0xc40 cryptomgr_test+0x47/0x80 kthread+0x4e1/0x620 ret_from_fork+0x37/0x70 ret_from_fork_asm+0x1a/0x30 These leaks comes from 'test_acomp()' where an extra requests chained to the head one (e.g. 'reqs[0]') are never freed. Fix this by unchaining and freeing such an extra requests in 'acomp_request_free()'. (I'm new to this subsystem and not sure about Fixes: tag BTW). Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru> --- include/crypto/acompress.h | 28 ++++++++++++++++++++++------ include/linux/crypto.h | 5 +++++ 2 files changed, 27 insertions(+), 6 deletions(-)