[PATCH v1] mm: zswap: Fix a potential memory leak in zswap_decompress().

From: Kanchana P Sridhar
Date: Wed Nov 13 2024 - 00:24:25 EST


This is a hotfix for a potential zpool memory leak that could result in
the existing zswap_decompress():

mutex_unlock(&acomp_ctx->mutex);

if (src != acomp_ctx->buffer)
zpool_unmap_handle(zpool, entry->handle);

Releasing the lock before the conditional does not protect the integrity of
"src", which is set earlier under the acomp_ctx mutex lock. This poses a
risk for the conditional behaving as intended, and consequently not
unmapping the zpool handle, which could cause a zswap zpool memory leak.

This patch moves the mutex_unlock() to occur after the conditional and
subsequent zpool_unmap_handle(). This ensures that the value of "src"
obtained earlier, with the mutex locked, does not change.

Even though an actual memory leak was not observed, this fix seems like a
cleaner implementation.

Signed-off-by: Kanchana P Sridhar <kanchana.p.sridhar@xxxxxxxxx>
Fixes: 9c500835f279 ("mm: zswap: fix kernel BUG in sg_init_one")
---
mm/zswap.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/mm/zswap.c b/mm/zswap.c
index f6316b66fb23..58810fa8ff23 100644
--- a/mm/zswap.c
+++ b/mm/zswap.c
@@ -986,10 +986,11 @@ static void zswap_decompress(struct zswap_entry *entry, struct folio *folio)
acomp_request_set_params(acomp_ctx->req, &input, &output, entry->length, PAGE_SIZE);
BUG_ON(crypto_wait_req(crypto_acomp_decompress(acomp_ctx->req), &acomp_ctx->wait));
BUG_ON(acomp_ctx->req->dlen != PAGE_SIZE);
- mutex_unlock(&acomp_ctx->mutex);

if (src != acomp_ctx->buffer)
zpool_unmap_handle(zpool, entry->handle);
+
+ mutex_unlock(&acomp_ctx->mutex);
}

/*********************************

base-commit: 0e5bdedb39ded767bff4c6184225578595cee98c
--
2.27.0