diff options
| author | Malaya Kumar Rout <mrout@redhat.com> | 2025-12-30 17:26:13 +0530 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-01-17 16:35:14 +0100 |
| commit | b7a883b0135dbc6817e90a829421c9fc8cd94bad (patch) | |
| tree | 047f7d6cf08efdd6bd8a13d51aa22de8c497bad6 /kernel | |
| parent | ea7a54393d50c60943c71f15e607d8fac0c686fc (diff) | |
| download | linux-b7a883b0135dbc6817e90a829421c9fc8cd94bad.tar.gz linux-b7a883b0135dbc6817e90a829421c9fc8cd94bad.tar.bz2 linux-b7a883b0135dbc6817e90a829421c9fc8cd94bad.zip | |
PM: hibernate: Fix crash when freeing invalid crypto compressor
commit 7966cf0ebe32c981bfa3db252cb5fc3bb1bf2e77 upstream.
When crypto_alloc_acomp() fails, it returns an ERR_PTR value, not NULL.
The cleanup code in save_compressed_image() and load_compressed_image()
unconditionally calls crypto_free_acomp() without checking for ERR_PTR,
which causes crypto_acomp_tfm() to dereference an invalid pointer and
crash the kernel.
This can be triggered when the compression algorithm is unavailable
(e.g., CONFIG_CRYPTO_LZO not enabled).
Fix by adding IS_ERR_OR_NULL() checks before calling crypto_free_acomp()
and acomp_request_free(), similar to the existing kthread_stop() check.
Fixes: b03d542c3c95 ("PM: hibernate: Use crypto_acomp interface")
Signed-off-by: Malaya Kumar Rout <mrout@redhat.com>
Cc: 6.15+ <stable@vger.kernel.org> # 6.15+
[ rjw: Added 2 empty code lines ]
Link: https://patch.msgid.link/20251230115613.64080-1-mrout@redhat.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/power/swap.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 70ae21f7370d..f910a250ccdd 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c @@ -897,8 +897,11 @@ out_clean: for (thr = 0; thr < nr_threads; thr++) { if (data[thr].thr) kthread_stop(data[thr].thr); - acomp_request_free(data[thr].cr); - crypto_free_acomp(data[thr].cc); + if (data[thr].cr) + acomp_request_free(data[thr].cr); + + if (!IS_ERR_OR_NULL(data[thr].cc)) + crypto_free_acomp(data[thr].cc); } vfree(data); } @@ -1519,8 +1522,11 @@ out_clean: for (thr = 0; thr < nr_threads; thr++) { if (data[thr].thr) kthread_stop(data[thr].thr); - acomp_request_free(data[thr].cr); - crypto_free_acomp(data[thr].cc); + if (data[thr].cr) + acomp_request_free(data[thr].cr); + + if (!IS_ERR_OR_NULL(data[thr].cc)) + crypto_free_acomp(data[thr].cc); } vfree(data); } |
