]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
power: reset: nvmem-reboot-mode: respect cell size for nvmem_cell_write
authorAlexander Koskovich <AKoskovich@pm.me>
Sun, 14 Dec 2025 19:16:18 +0000 (19:16 +0000)
committerSebastian Reichel <sebastian.reichel@collabora.com>
Mon, 12 Jan 2026 01:52:31 +0000 (02:52 +0100)
Some platforms expose reboot mode cells that are smaller than an
unsigned int, in which cases lead to write failures. Read the cell
first to determine actual size and only write the number of bytes the
cell can hold.

Fixes: 7a78a7f7695b ("power: reset: nvmem-reboot-mode: use NVMEM as reboot mode write interface")
Signed-off-by: Alexander Koskovich <akoskovich@pm.me>
Link: https://patch.msgid.link/20251214191529.2470580-1-akoskovich@pm.me
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
drivers/power/reset/nvmem-reboot-mode.c

index 41530b70cfc48c2a83fbbd96f523d5816960a0d1..d260715fccf67f9f072bb56c5defbf885750650e 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/nvmem-consumer.h>
 #include <linux/platform_device.h>
 #include <linux/reboot-mode.h>
+#include <linux/slab.h>
 
 struct nvmem_reboot_mode {
        struct reboot_mode_driver reboot;
@@ -19,12 +20,22 @@ struct nvmem_reboot_mode {
 static int nvmem_reboot_mode_write(struct reboot_mode_driver *reboot,
                                    unsigned int magic)
 {
-       int ret;
        struct nvmem_reboot_mode *nvmem_rbm;
+       size_t buf_len;
+       void *buf;
+       int ret;
 
        nvmem_rbm = container_of(reboot, struct nvmem_reboot_mode, reboot);
 
-       ret = nvmem_cell_write(nvmem_rbm->cell, &magic, sizeof(magic));
+       buf = nvmem_cell_read(nvmem_rbm->cell, &buf_len);
+       if (IS_ERR(buf))
+               return PTR_ERR(buf);
+       kfree(buf);
+
+       if (buf_len > sizeof(magic))
+               return -EINVAL;
+
+       ret = nvmem_cell_write(nvmem_rbm->cell, &magic, buf_len);
        if (ret < 0)
                dev_err(reboot->dev, "update reboot mode bits failed\n");