* [PATCH 1/2] EDAC/device_sysfs: Use kstrtouint for poll_msec to prevent truncation
@ 2026-07-30 14:55 Jad Keskes
2026-07-30 14:55 ` [PATCH 2/2] EDAC/device: Serialize poll_msec store against device teardown Jad Keskes
0 siblings, 1 reply; 2+ messages in thread
From: Jad Keskes @ 2026-07-30 14:55 UTC (permalink / raw)
To: linux-edac
Cc: linux-kernel, Borislav Petkov, Mauro Carvalho Chehab, Tony Luck,
James Morse, Robert Richter, Jad Keskes
The poll_msec sysfs store uses simple_strtoul() which accepts an
unsigned long, but the target field (poll_msec) is unsigned int. On
64-bit systems, a value > UINT_MAX is silently truncated when stored.
Fix the mismatch by using kstrtouint() instead. This rejects values
> UINT_MAX at parse time, making truncation impossible. Also add a
check for value < 1 to reject the 0-delay case, which would cause the
poll work to spin without delay and consume 100% CPU.
Fixes: e27e3dac6517 ("drivers/edac: add edac_device class")
Signed-off-by: Jad Keskes <inasj268@gmail.com>
---
drivers/edac/edac_device_sysfs.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/edac/edac_device_sysfs.c b/drivers/edac/edac_device_sysfs.c
index ac678b4a21fc..e2ee5c6c56d3 100644
--- a/drivers/edac/edac_device_sysfs.c
+++ b/drivers/edac/edac_device_sysfs.c
@@ -90,14 +90,21 @@ static ssize_t edac_device_ctl_poll_msec_store(struct edac_device_ctl_info
*ctl_info, const char *data,
size_t count)
{
- unsigned long value;
+ unsigned int value;
+ int ret;
/* get the value and enforce that it is non-zero, must be at least
* one millisecond for the delay period, between scans
* Then cancel last outstanding delay for the work request
* and set a new one.
*/
- value = simple_strtoul(data, NULL, 0);
+ ret = kstrtouint(data, 0, &value);
+ if (ret < 0)
+ return ret;
+
+ if (value < 1)
+ return -EINVAL;
+
edac_device_reset_delay_period(ctl_info, value);
return count;
--
2.55.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH 2/2] EDAC/device: Serialize poll_msec store against device teardown
2026-07-30 14:55 [PATCH 1/2] EDAC/device_sysfs: Use kstrtouint for poll_msec to prevent truncation Jad Keskes
@ 2026-07-30 14:55 ` Jad Keskes
0 siblings, 0 replies; 2+ messages in thread
From: Jad Keskes @ 2026-07-30 14:55 UTC (permalink / raw)
To: linux-edac
Cc: linux-kernel, Borislav Petkov, Mauro Carvalho Chehab, Tony Luck,
James Morse, Robert Richter, Jad Keskes
edac_device_reset_delay_period() unconditionally calls edac_mod_work()
to re-arm the workqueue timer when the poll_msec sysfs attribute is
written. This has two issues:
1) Interrupt-driven devices (op_state = OP_RUNNING_INTERRUPT) have
no initialized workqueue, so calling edac_mod_work() would operate
on uninitialized timer state.
2) A concurrent write to poll_msec during device removal can race
with edac_device_del_device(). Even with an OP_OFFLINE state check,
the check and edac_mod_work() are not atomic, allowing the workqueue
to be re-armed after teardown.
Fix both by holding device_ctls_mutex around the state check and
edac_mod_work() call in reset_delay_period(), and moving the workqueue
teardown inside the same mutex in del_device(). With the mutex held in
both paths:
- reset_delay_period() atomically verifies op_state == OP_RUNNING_POLL
before re-arming; any other state skips the call entirely.
- del_device() sets OP_OFFLINE and tears down the workqueue while
holding the mutex, so any racing reset_delay_period() completes
before teardown or sees OP_OFFLINE and bails.
Also fix the parameter type from unsigned long to unsigned int to match
the poll_msec field, and fix a latent bug where round_jiffies_relative()
received a millisecond value instead of jiffies.
Signed-off-by: Jad Keskes <inasj268@gmail.com>
---
drivers/edac/edac_device.c | 15 +++++++++++----
drivers/edac/edac_module.h | 2 +-
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/edac/edac_device.c b/drivers/edac/edac_device.c
index 19522c568aa5..3fb4de3ed28c 100644
--- a/drivers/edac/edac_device.c
+++ b/drivers/edac/edac_device.c
@@ -394,17 +394,24 @@ static void edac_device_workq_teardown(struct edac_device_ctl_info *edac_dev)
* Then restart the workq on the new delay
*/
void edac_device_reset_delay_period(struct edac_device_ctl_info *edac_dev,
- unsigned long value)
+ unsigned int value)
{
unsigned long jiffs = msecs_to_jiffies(value);
if (value == 1000)
- jiffs = round_jiffies_relative(value);
+ jiffs = round_jiffies_relative(jiffs);
+
+ mutex_lock(&device_ctls_mutex);
+ if (edac_dev->op_state != OP_RUNNING_POLL) {
+ mutex_unlock(&device_ctls_mutex);
+ return;
+ }
edac_dev->poll_msec = value;
edac_dev->delay = jiffs;
edac_mod_work(&edac_dev->work, jiffs);
+ mutex_unlock(&device_ctls_mutex);
}
int edac_device_alloc_index(void)
@@ -492,11 +499,11 @@ struct edac_device_ctl_info *edac_device_del_device(struct device *dev)
/* deregister from global list */
del_edac_device_from_global_list(edac_dev);
- mutex_unlock(&device_ctls_mutex);
-
/* clear workq processing on this instance */
edac_device_workq_teardown(edac_dev);
+ mutex_unlock(&device_ctls_mutex);
+
/* Tear down the sysfs entries for this instance */
edac_device_remove_sysfs(edac_dev);
diff --git a/drivers/edac/edac_module.h b/drivers/edac/edac_module.h
index 96f6de0c8ff6..e03ec7daa64a 100644
--- a/drivers/edac/edac_module.h
+++ b/drivers/edac/edac_module.h
@@ -56,7 +56,7 @@ bool edac_stop_work(struct delayed_work *work);
bool edac_mod_work(struct delayed_work *work, unsigned long delay);
extern void edac_device_reset_delay_period(struct edac_device_ctl_info
- *edac_dev, unsigned long value);
+ *edac_dev, unsigned int value);
extern void edac_mc_reset_delay_period(unsigned long value);
/*
--
2.55.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-07-30 14:56 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-30 14:55 [PATCH 1/2] EDAC/device_sysfs: Use kstrtouint for poll_msec to prevent truncation Jad Keskes
2026-07-30 14:55 ` [PATCH 2/2] EDAC/device: Serialize poll_msec store against device teardown Jad Keskes
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.