mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Andrea Parri <parri.andrea@gmail.com>
To: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Andrea Parri <parri.andrea@gmail.com>,
	Len Brown <lenb@kernel.org>, Pavel Machek <pavel@kernel.org>,
	Bojan Smojver <bojan@rexursive.com>,
	linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH] PM: hibernate: Wait for in-flight reads before freeing the read-ahead ring
Date: Wed, 30 Sep 2026 16:08:49 +0200	[thread overview]
Message-ID: <20260930140850.4864-1-parri.andrea@gmail.com> (raw)

load_compressed_image() reads the image ahead into a ring of pages with
asynchronous bios, and waits for them only when fewer than CMP_PAGES
pages are buffered. From the second loop pass on, reads into the rest of
the ring are thus in flight while buffered data is parsed and
decompressed.

The exits taken on an invalid compressed length, a failed decompression,
an invalid uncompressed length or a snapshot_write_next() error jump to
out_finish without waiting for those reads. The function then frees the
ring pages and returns, releasing the hib_bio_batch on its stack, while
the outstanding bios still write into the freed pages and hib_end_io()
still updates and wakes the stale batch.

A corrupted image is what fails these checks, as the CRC32 is only
compared once the whole image has been loaded. With such an image, the
resume fails with "Failed to load image, recovering." and the boot
continues on top of the resulting memory corruption.

Wait for the batch at out_finish, as save_compressed_image() and
load_image() already do before releasing their buffers. hib_wait_io()
returns at once when no reads are outstanding, so exits without
read-ahead in flight are unaffected.

This was found by code inspection. It has only been build-tested; no
reproducer was run.

Fixes: 081a9d043c98 ("PM / Hibernate: Improve performance of LZO/plain hibernation, checksum image")
Assisted-by: LLM
Signed-off-by: Andrea Parri <parri.andrea@gmail.com>
---
 kernel/power/swap.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/kernel/power/swap.c b/kernel/power/swap.c
index c78f1593600bb..49b3da89b49d4 100644
--- a/kernel/power/swap.c
+++ b/kernel/power/swap.c
@@ -1198,6 +1198,7 @@ static int load_compressed_image(struct swap_map_handle *handle,
 {
 	unsigned int m;
 	int ret = 0;
+	int err2;
 	int eof = 0;
 	struct hib_bio_batch hb;
 	ktime_t start;
@@ -1478,6 +1479,10 @@ static int load_compressed_image(struct swap_map_handle *handle,
 	}
 
 out_finish:
+	/* Error exits may leave reads in flight into page[]. */
+	err2 = hib_wait_io(&hb);
+	if (!ret)
+		ret = err2;
 	if (crc->run_threads) {
 		wait_event(crc->done, atomic_read_acquire(&crc->stop));
 		atomic_set(&crc->stop, 0);
-- 
2.53.0


                 reply	other threads:[~2026-09-30 14:09 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260930140850.4864-1-parri.andrea@gmail.com \
    --to=parri.andrea@gmail.com \
    --cc=bojan@rexursive.com \
    --cc=lenb@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=pavel@kernel.org \
    --cc=rafael@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®