* [PATCH 0/2] iio: hid-sensors: fix shared callbacks in temperature and humidity
@ 2026-10-07 7:23 Christopher Hoover
2026-10-07 7:23 ` [PATCH 1/2] iio: temperature: hid-sensor-temperature: Use per-instance callbacks Christopher Hoover
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Christopher Hoover @ 2026-10-07 7:23 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Jiri Kosina, Srinivas Pandruvada, David Lechner, Nuno Sá,
Andy Shevchenko, linux-iio, linux-input, linux-kernel,
Christopher Hoover
hid-sensor-temperature and hid-sensor-humidity keep a single static
struct hid_sensor_hub_callbacks for all of their instances and
overwrite its pdev on every probe. The other HID sensor drivers keep
theirs per instance. With two temperature sensors, input reports for
one are delivered with the other's platform device; once that device
is removed, platform_get_drvdata() returns NULL and
temperature_capture_sample() dereferences it:
BUG: kernel NULL pointer dereference, address: 00000000000003a8
RIP: 0010:temperature_capture_sample+0xd/0x50 [hid_sensor_temperature]
Call Trace:
sensor_hub_raw_event+0x3fc/0x7a0 [hid_sensor_hub]
__hid_input_report+0x140/0x230 [hid]
hid_safe_input_report+0x14/0x30 [hid]
uhid_char_write+0x1f6/0x340 [uhid]
The oops happens with the hub's spinlock held, so the hub's removal
then hangs until reboot.
I hit this with a userspace daemon that presents a USB thermometer as
a HID temperature sensor through uhid: creating a second uhid sensor
and destroying it while the first keeps sending input reports
reproduced it twice on 7.0.
The patches move the callbacks into each driver's state, as
hid-sensor-accel-3d does. Humidity has the same code but I have not
reproduced it there.
Not addressed here: sensor_hub_raw_event() looks up the callback under
dyn_callback_lock and calls it under pdata->lock, while
sensor_hub_remove_callback() takes only dyn_callback_lock, so a
report racing a remove can still reach a callback whose driver is
going away. That predates this series.
Christopher Hoover (2):
iio: temperature: hid-sensor-temperature: Use per-instance callbacks
iio: humidity: hid-sensor-humidity: Use per-instance callbacks
drivers/iio/humidity/hid-sensor-humidity.c | 12 +++++-------
drivers/iio/temperature/hid-sensor-temperature.c | 12 +++++-------
2 files changed, 10 insertions(+), 14 deletions(-)
base-commit: 9ee8306121495d2a25aa5d1bfd519f2748786b83
--
2.43.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/2] iio: temperature: hid-sensor-temperature: Use per-instance callbacks
2026-10-07 7:23 [PATCH 0/2] iio: hid-sensors: fix shared callbacks in temperature and humidity Christopher Hoover
@ 2026-10-07 7:23 ` Christopher Hoover
2026-10-07 7:23 ` [PATCH 2/2] iio: humidity: hid-sensor-humidity: " Christopher Hoover
2026-10-07 18:44 ` [PATCH v2 0/3] iio: hid-sensors: fix shared callbacks in temperature and humidity Christopher Hoover
2 siblings, 0 replies; 7+ messages in thread
From: Christopher Hoover @ 2026-10-07 7:23 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Jiri Kosina, Srinivas Pandruvada, David Lechner, Nuno Sá,
Andy Shevchenko, linux-iio, linux-input, linux-kernel,
Christopher Hoover, stable
hid-sensor-temperature keeps a single static struct
hid_sensor_hub_callbacks for all instances and overwrites its pdev in
every probe. With two temperature sensors, input reports for one are
delivered with the other's platform device; once that device is
removed, platform_get_drvdata() returns NULL and
temperature_capture_sample() dereferences it:
BUG: kernel NULL pointer dereference, address: 00000000000003a8
RIP: 0010:temperature_capture_sample+0xd/0x50 [hid_sensor_temperature]
The oops happens in sensor_hub_raw_event() with the hub's spinlock
held, so the hub's removal then hangs. It reproduces with two uhid
devices that each declare a temperature sensor, one destroyed while
the other still sends input reports.
Keep the callbacks in struct temperature_state, as the other HID
sensor drivers (accel, gyro, als, ...) do.
Fixes: 59d0f2da3569 ("iio: hid: Add temperature sensor support")
Cc: stable@vger.kernel.org
Signed-off-by: Christopher Hoover <ch@murgatroid.com>
---
drivers/iio/temperature/hid-sensor-temperature.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/iio/temperature/hid-sensor-temperature.c b/drivers/iio/temperature/hid-sensor-temperature.c
index 5e3262e461f4..35b8643305b9 100644
--- a/drivers/iio/temperature/hid-sensor-temperature.c
+++ b/drivers/iio/temperature/hid-sensor-temperature.c
@@ -14,6 +14,7 @@
struct temperature_state {
struct hid_sensor_common common_attributes;
+ struct hid_sensor_hub_callbacks callbacks;
struct hid_sensor_hub_attribute_info temperature_attr;
struct {
s32 temperature_data;
@@ -181,11 +182,6 @@ static int temperature_parse_report(struct platform_device *pdev,
return ret;
}
-static struct hid_sensor_hub_callbacks temperature_callbacks = {
- .send_event = &temperature_proc_event,
- .capture_sample = &temperature_capture_sample,
-};
-
/* Function to initialize the processing for usage id */
static int hid_temperature_probe(struct platform_device *pdev)
{
@@ -237,9 +233,11 @@ static int hid_temperature_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, indio_dev);
- temperature_callbacks.pdev = pdev;
+ temp_st->callbacks.send_event = temperature_proc_event;
+ temp_st->callbacks.capture_sample = temperature_capture_sample;
+ temp_st->callbacks.pdev = pdev;
ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_TEMPERATURE,
- &temperature_callbacks);
+ &temp_st->callbacks);
if (ret)
goto error_remove_trigger;
--
2.43.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/2] iio: humidity: hid-sensor-humidity: Use per-instance callbacks
2026-10-07 7:23 [PATCH 0/2] iio: hid-sensors: fix shared callbacks in temperature and humidity Christopher Hoover
2026-10-07 7:23 ` [PATCH 1/2] iio: temperature: hid-sensor-temperature: Use per-instance callbacks Christopher Hoover
@ 2026-10-07 7:23 ` Christopher Hoover
2026-10-07 18:44 ` [PATCH v2 0/3] iio: hid-sensors: fix shared callbacks in temperature and humidity Christopher Hoover
2 siblings, 0 replies; 7+ messages in thread
From: Christopher Hoover @ 2026-10-07 7:23 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Jiri Kosina, Srinivas Pandruvada, David Lechner, Nuno Sá,
Andy Shevchenko, linux-iio, linux-input, linux-kernel,
Christopher Hoover, stable
hid-sensor-humidity keeps a single static struct
hid_sensor_hub_callbacks for all instances and overwrites its pdev in
every probe, so with two humidity sensors, input reports for one are
delivered with the other's platform device, and a NULL dereference
follows once that device is removed. The same bug was found in
hid-sensor-temperature, which shares this code.
Keep the callbacks in struct hid_humidity_state, as the other HID
sensor drivers (accel, gyro, als, ...) do.
Fixes: d7ed89d5aadf ("iio: hid: Add humidity sensor support")
Cc: stable@vger.kernel.org
Signed-off-by: Christopher Hoover <ch@murgatroid.com>
---
drivers/iio/humidity/hid-sensor-humidity.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/iio/humidity/hid-sensor-humidity.c b/drivers/iio/humidity/hid-sensor-humidity.c
index 7cec81ff5685..95ee1d71c1a7 100644
--- a/drivers/iio/humidity/hid-sensor-humidity.c
+++ b/drivers/iio/humidity/hid-sensor-humidity.c
@@ -14,6 +14,7 @@
struct hid_humidity_state {
struct hid_sensor_common common_attributes;
+ struct hid_sensor_hub_callbacks callbacks;
struct hid_sensor_hub_attribute_info humidity_attr;
struct {
s32 humidity_data;
@@ -184,11 +185,6 @@ static int humidity_parse_report(struct platform_device *pdev,
return ret;
}
-static struct hid_sensor_hub_callbacks humidity_callbacks = {
- .send_event = &humidity_proc_event,
- .capture_sample = &humidity_capture_sample,
-};
-
/* Function to initialize the processing for usage id */
static int hid_humidity_probe(struct platform_device *pdev)
{
@@ -240,9 +236,11 @@ static int hid_humidity_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, indio_dev);
- humidity_callbacks.pdev = pdev;
+ humid_st->callbacks.send_event = humidity_proc_event;
+ humid_st->callbacks.capture_sample = humidity_capture_sample;
+ humid_st->callbacks.pdev = pdev;
ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_HUMIDITY,
- &humidity_callbacks);
+ &humid_st->callbacks);
if (ret)
goto error_remove_trigger;
--
2.43.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 0/3] iio: hid-sensors: fix shared callbacks in temperature and humidity
2026-10-07 7:23 [PATCH 0/2] iio: hid-sensors: fix shared callbacks in temperature and humidity Christopher Hoover
2026-10-07 7:23 ` [PATCH 1/2] iio: temperature: hid-sensor-temperature: Use per-instance callbacks Christopher Hoover
2026-10-07 7:23 ` [PATCH 2/2] iio: humidity: hid-sensor-humidity: " Christopher Hoover
@ 2026-10-07 18:44 ` Christopher Hoover
2026-10-07 18:44 ` [PATCH v2 1/3] HID: hid-sensor-hub: Synchronize callback removal with raw events Christopher Hoover
` (2 more replies)
2 siblings, 3 replies; 7+ messages in thread
From: Christopher Hoover @ 2026-10-07 18:44 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Jiri Kosina, Benjamin Tissoires, Srinivas Pandruvada,
David Lechner, nuno.sa, Andy Shevchenko, linux-iio, linux-input,
linux-kernel, Christopher Hoover
hid-sensor-temperature and hid-sensor-humidity share one static
struct hid_sensor_hub_callbacks across instances and overwrite its pdev
on every probe. With two temperature sensors, reports for one go to
the other's pdev; once that device is removed,
temperature_capture_sample() dereferences NULL. I hit this on 7.0
with two uhid-created sensors.
Patches 2-3 make the callbacks per instance, as the other HID sensor
drivers do. Patch 1 makes sensor_hub_remove_callback() take
pdata->lock, as sensor_hub_raw_event() does, so a report racing an
unbind cannot call through the freed callbacks.
Changes in v2:
- New patch 1, for the use-after-free on unbind found by the Sashiko
review of v1.
Christopher Hoover (3):
HID: hid-sensor-hub: Synchronize callback removal with raw events
iio: temperature: hid-sensor-temperature: Use per-instance callbacks
iio: humidity: hid-sensor-humidity: Use per-instance callbacks
drivers/hid/hid-sensor-hub.c | 12 ++++++++++--
drivers/iio/humidity/hid-sensor-humidity.c | 12 +++++-------
drivers/iio/temperature/hid-sensor-temperature.c | 12 +++++-------
3 files changed, 20 insertions(+), 16 deletions(-)
base-commit: 9ee8306121495d2a25aa5d1bfd519f2748786b83
--
2.43.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 1/3] HID: hid-sensor-hub: Synchronize callback removal with raw events
2026-10-07 18:44 ` [PATCH v2 0/3] iio: hid-sensors: fix shared callbacks in temperature and humidity Christopher Hoover
@ 2026-10-07 18:44 ` Christopher Hoover
2026-10-07 18:44 ` [PATCH v2 2/3] iio: temperature: hid-sensor-temperature: Use per-instance callbacks Christopher Hoover
2026-10-07 18:44 ` [PATCH v2 3/3] iio: humidity: hid-sensor-humidity: " Christopher Hoover
2 siblings, 0 replies; 7+ messages in thread
From: Christopher Hoover @ 2026-10-07 18:44 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Jiri Kosina, Benjamin Tissoires, Srinivas Pandruvada,
David Lechner, nuno.sa, Andy Shevchenko, linux-iio, linux-input,
linux-kernel, Christopher Hoover, stable
sensor_hub_raw_event() holds pdata->lock while it looks a callback up
in dyn_callback_list and calls its capture_sample() and send_event().
sensor_hub_remove_callback() takes only dyn_callback_lock, so it can
unlink a callback and return while another CPU is between the lookup
and the call. The sensor drivers remove their callback in .remove()
and keep the struct hid_sensor_hub_callbacks in memory that devres
frees right after, so a report racing an unbind can call through
freed function pointers.
Take pdata->lock in sensor_hub_remove_callback() too, outside
dyn_callback_lock as in sensor_hub_raw_event(), so the removal waits
for a report in flight. pdata->lock is otherwise only taken in
sensor_hub_raw_event(), and callbacks are removed from process
context.
Fixes: 401ca24fb34a ("HID: sensors: introduce sensor framework")
Cc: stable@vger.kernel.org
Signed-off-by: Christopher Hoover <ch@murgatroid.com>
---
drivers/hid/hid-sensor-hub.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
index 6470a290ebfc..7cf9f398592e 100644
--- a/drivers/hid/hid-sensor-hub.c
+++ b/drivers/hid/hid-sensor-hub.c
@@ -173,7 +173,14 @@ int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev,
struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev);
unsigned long flags;
- spin_lock_irqsave(&pdata->dyn_callback_lock, flags);
+ /*
+ * sensor_hub_raw_event() holds pdata->lock while it looks up a
+ * callback and calls it. Taking it here too means no report is
+ * still using the callback once it is unlinked, so its owner may
+ * free it as soon as this returns.
+ */
+ spin_lock_irqsave(&pdata->lock, flags);
+ spin_lock(&pdata->dyn_callback_lock);
list_for_each_entry(callback, &pdata->dyn_callback_list, list)
if (callback->usage_id == usage_id &&
callback->hsdev == hsdev) {
@@ -181,7 +188,8 @@ int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev,
kfree(callback);
break;
}
- spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
+ spin_unlock(&pdata->dyn_callback_lock);
+ spin_unlock_irqrestore(&pdata->lock, flags);
return 0;
}
--
2.43.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 2/3] iio: temperature: hid-sensor-temperature: Use per-instance callbacks
2026-10-07 18:44 ` [PATCH v2 0/3] iio: hid-sensors: fix shared callbacks in temperature and humidity Christopher Hoover
2026-10-07 18:44 ` [PATCH v2 1/3] HID: hid-sensor-hub: Synchronize callback removal with raw events Christopher Hoover
@ 2026-10-07 18:44 ` Christopher Hoover
2026-10-07 18:44 ` [PATCH v2 3/3] iio: humidity: hid-sensor-humidity: " Christopher Hoover
2 siblings, 0 replies; 7+ messages in thread
From: Christopher Hoover @ 2026-10-07 18:44 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Jiri Kosina, Benjamin Tissoires, Srinivas Pandruvada,
David Lechner, nuno.sa, Andy Shevchenko, linux-iio, linux-input,
linux-kernel, Christopher Hoover, stable
hid-sensor-temperature keeps a single static struct
hid_sensor_hub_callbacks for all instances and overwrites its pdev in
every probe. With two temperature sensors, input reports for one are
delivered with the other's platform device; once that device is
removed, platform_get_drvdata() returns NULL and
temperature_capture_sample() dereferences it:
BUG: kernel NULL pointer dereference, address: 00000000000003a8
RIP: 0010:temperature_capture_sample+0xd/0x50 [hid_sensor_temperature]
The oops happens in sensor_hub_raw_event() with the hub's spinlock
held, so the hub's removal then hangs. It reproduces with two uhid
devices that each declare a temperature sensor, one destroyed while
the other still sends input reports.
Keep the callbacks in struct temperature_state, as the other HID
sensor drivers (accel, gyro, als, ...) do.
Fixes: 59d0f2da3569 ("iio: hid: Add temperature sensor support")
Cc: stable@vger.kernel.org
Signed-off-by: Christopher Hoover <ch@murgatroid.com>
---
drivers/iio/temperature/hid-sensor-temperature.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/iio/temperature/hid-sensor-temperature.c b/drivers/iio/temperature/hid-sensor-temperature.c
index 5e3262e461f4..35b8643305b9 100644
--- a/drivers/iio/temperature/hid-sensor-temperature.c
+++ b/drivers/iio/temperature/hid-sensor-temperature.c
@@ -14,6 +14,7 @@
struct temperature_state {
struct hid_sensor_common common_attributes;
+ struct hid_sensor_hub_callbacks callbacks;
struct hid_sensor_hub_attribute_info temperature_attr;
struct {
s32 temperature_data;
@@ -181,11 +182,6 @@ static int temperature_parse_report(struct platform_device *pdev,
return ret;
}
-static struct hid_sensor_hub_callbacks temperature_callbacks = {
- .send_event = &temperature_proc_event,
- .capture_sample = &temperature_capture_sample,
-};
-
/* Function to initialize the processing for usage id */
static int hid_temperature_probe(struct platform_device *pdev)
{
@@ -237,9 +233,11 @@ static int hid_temperature_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, indio_dev);
- temperature_callbacks.pdev = pdev;
+ temp_st->callbacks.send_event = temperature_proc_event;
+ temp_st->callbacks.capture_sample = temperature_capture_sample;
+ temp_st->callbacks.pdev = pdev;
ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_TEMPERATURE,
- &temperature_callbacks);
+ &temp_st->callbacks);
if (ret)
goto error_remove_trigger;
--
2.43.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 3/3] iio: humidity: hid-sensor-humidity: Use per-instance callbacks
2026-10-07 18:44 ` [PATCH v2 0/3] iio: hid-sensors: fix shared callbacks in temperature and humidity Christopher Hoover
2026-10-07 18:44 ` [PATCH v2 1/3] HID: hid-sensor-hub: Synchronize callback removal with raw events Christopher Hoover
2026-10-07 18:44 ` [PATCH v2 2/3] iio: temperature: hid-sensor-temperature: Use per-instance callbacks Christopher Hoover
@ 2026-10-07 18:44 ` Christopher Hoover
2 siblings, 0 replies; 7+ messages in thread
From: Christopher Hoover @ 2026-10-07 18:44 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Jiri Kosina, Benjamin Tissoires, Srinivas Pandruvada,
David Lechner, nuno.sa, Andy Shevchenko, linux-iio, linux-input,
linux-kernel, Christopher Hoover, stable
hid-sensor-humidity keeps a single static struct
hid_sensor_hub_callbacks for all instances and overwrites its pdev in
every probe, so with two humidity sensors, input reports for one are
delivered with the other's platform device, and a NULL dereference
follows once that device is removed. The same bug was found in
hid-sensor-temperature, which shares this code.
Keep the callbacks in struct hid_humidity_state, as the other HID
sensor drivers (accel, gyro, als, ...) do.
Fixes: d7ed89d5aadf ("iio: hid: Add humidity sensor support")
Cc: stable@vger.kernel.org
Signed-off-by: Christopher Hoover <ch@murgatroid.com>
---
drivers/iio/humidity/hid-sensor-humidity.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/iio/humidity/hid-sensor-humidity.c b/drivers/iio/humidity/hid-sensor-humidity.c
index 7cec81ff5685..95ee1d71c1a7 100644
--- a/drivers/iio/humidity/hid-sensor-humidity.c
+++ b/drivers/iio/humidity/hid-sensor-humidity.c
@@ -14,6 +14,7 @@
struct hid_humidity_state {
struct hid_sensor_common common_attributes;
+ struct hid_sensor_hub_callbacks callbacks;
struct hid_sensor_hub_attribute_info humidity_attr;
struct {
s32 humidity_data;
@@ -184,11 +185,6 @@ static int humidity_parse_report(struct platform_device *pdev,
return ret;
}
-static struct hid_sensor_hub_callbacks humidity_callbacks = {
- .send_event = &humidity_proc_event,
- .capture_sample = &humidity_capture_sample,
-};
-
/* Function to initialize the processing for usage id */
static int hid_humidity_probe(struct platform_device *pdev)
{
@@ -240,9 +236,11 @@ static int hid_humidity_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, indio_dev);
- humidity_callbacks.pdev = pdev;
+ humid_st->callbacks.send_event = humidity_proc_event;
+ humid_st->callbacks.capture_sample = humidity_capture_sample;
+ humid_st->callbacks.pdev = pdev;
ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_HUMIDITY,
- &humidity_callbacks);
+ &humid_st->callbacks);
if (ret)
goto error_remove_trigger;
--
2.43.0
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-10-07 18:55 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-07 7:23 [PATCH 0/2] iio: hid-sensors: fix shared callbacks in temperature and humidity Christopher Hoover
2026-10-07 7:23 ` [PATCH 1/2] iio: temperature: hid-sensor-temperature: Use per-instance callbacks Christopher Hoover
2026-10-07 7:23 ` [PATCH 2/2] iio: humidity: hid-sensor-humidity: " Christopher Hoover
2026-10-07 18:44 ` [PATCH v2 0/3] iio: hid-sensors: fix shared callbacks in temperature and humidity Christopher Hoover
2026-10-07 18:44 ` [PATCH v2 1/3] HID: hid-sensor-hub: Synchronize callback removal with raw events Christopher Hoover
2026-10-07 18:44 ` [PATCH v2 2/3] iio: temperature: hid-sensor-temperature: Use per-instance callbacks Christopher Hoover
2026-10-07 18:44 ` [PATCH v2 3/3] iio: humidity: hid-sensor-humidity: " Christopher Hoover
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®