[PATCH] Input: synaptics-rmi4 - reject concurrent firmware updates
From: Shuangpeng Bai <hidden>
Date: 2026-08-17 18:22:25
Also in:
stable
Subsystem:
input (keyboard, mouse, joystick, touchscreen) drivers, the rest · Maintainers:
Dmitry Torokhov, Linus Torvalds
The update_fw sysfs store callback can execute concurrently. Each
invocation runs rmi_firmware_update(), which tears down and rebuilds the
RMI function list.
If two writes overlap, both rmi_free_function_list() calls can walk the
same list and select the same rmi_function entry. One invocation can delete
and unregister the entry while the other still uses its iterator's fn
pointer, resulting in use-after-free or list corruption. This was
reproduced as list_del corruption in rmi_free_function_list().
Firmware flashing is an exclusive operation, and running a second update
concurrently has no useful semantics. Add a per-device update_mutex and
try to acquire it immediately before starting the update. Return -EBUSY if
another update is already active, and hold the mutex until the update has
completed so their function-list teardown cannot overlap.
The status attribute does not acquire update_mutex, so update_fw_status can
still be polled while an update is running.
Fixes: 29fd0ec2bdbe ("Input: synaptics-rmi4 - add support for F34 device reflash")
Cc: stable@vger.kernel.org
Signed-off-by: Shuangpeng Bai <redacted>
---
drivers/input/rmi4/rmi_driver.c | 1 +
drivers/input/rmi4/rmi_f34.c | 8 +++++---
include/linux/rmi.h | 1 +
3 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index 5d49a9021c7d..3a5cb17e938f 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c@@ -1218,6 +1218,7 @@ static int rmi_driver_probe(struct device *dev) mutex_init(&data->irq_mutex); mutex_init(&data->enabled_mutex); + mutex_init(&data->update_mutex); retval = rmi_probe_interrupts(data); if (retval)
diff --git a/drivers/input/rmi4/rmi_f34.c b/drivers/input/rmi4/rmi_f34.c
index f1947f03b06a..04f12165cab0 100644
--- a/drivers/input/rmi4/rmi_f34.c
+++ b/drivers/input/rmi4/rmi_f34.c@@ -468,13 +468,15 @@ static ssize_t rmi_driver_update_fw_store(struct device *dev, if (error) return error; + if (!mutex_trylock(&data->update_mutex)) + return -EBUSY; + dev_info(dev, "Flashing %s\n", fw_name); error = rmi_firmware_update(data, fw); - if (error) - return error; - return count; + mutex_unlock(&data->update_mutex); + return error ?: count; } static DEVICE_ATTR(update_fw, 0200, NULL, rmi_driver_update_fw_store);
diff --git a/include/linux/rmi.h b/include/linux/rmi.h
index ab7eea01ab42..d56c23240868 100644
--- a/include/linux/rmi.h
+++ b/include/linux/rmi.h@@ -340,6 +340,7 @@ struct rmi_driver_data { struct rmi_function *f01_container; struct rmi_function *f34_container; + struct mutex update_mutex; bool bootloader_mode; int num_of_irq_regs;
--
2.43.0