[PATCH 1/2] zram: fix out-of-bounds access in writeback_store()

Longlong Xia <[email protected]> Tue, 4 Aug 2026 14:59:18 +0800
Newsgroups org.kernel.vger.linux-block,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <[email protected]>
From: Longlong Xia <[email protected]>

writeback_store() calculates the table scan bounds before taking
dev_lock. A reset followed by reconfiguration with a smaller disksize
can therefore replace zram->table while writeback_store() is waiting for
the lock. Once it acquires the lock, it sees an initialized device but
scans the new table using the old upper bound, resulting in an
out-of-bounds access.

Calculate the number of pages while holding dev_lock so the scan bound
matches the table protected by the lock.

Fixes: a939888ec38b ("zram: support idle/huge page writeback")
Cc: <[email protected]>
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Longlong Xia <[email protected]>
---
 drivers/block/zram/zram_drv.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index ace65c586072..02fd64475a9a 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -1244,8 +1244,8 @@ static ssize_t writeback_store(struct device *dev,
 			       const char *buf, size_t len)
 {
 	struct zram *zram = dev_to_zram(dev);
-	u64 nr_pages = zram->disksize >> PAGE_SHIFT;
-	unsigned long lo = 0, hi = nr_pages;
+	u64 nr_pages;
+	unsigned long lo = 0, hi;
 	struct zram_pp_ctl *pp_ctl = NULL;
 	struct zram_wb_ctl *wb_ctl = NULL;
 	char *args, *param, *val;
@@ -1259,6 +1259,9 @@ static ssize_t writeback_store(struct device *dev,
 	if (!zram->backing_dev)
 		return -ENODEV;
 
+	nr_pages = zram->disksize >> PAGE_SHIFT;
+	hi = nr_pages;
+
 	pp_ctl = init_pp_ctl();
 	if (!pp_ctl)
 		return -ENOMEM;
-- 
2.43.0