* [PATCH v5 01/13] iio: hid-sensors: remove unused iio_dev argument
2026-08-06 12:25 [PATCH v5 00/13] HID: iio: Introduce devm_ APIs for HID sensors Sanjay Chitroda via B4 Relay
@ 2026-08-06 12:25 ` Sanjay Chitroda via B4 Relay
2026-08-06 12:37 ` sashiko-bot
2026-08-06 12:25 ` [PATCH v5 02/13] iio: hid-sensors: introduce device managed API Sanjay Chitroda via B4 Relay
` (11 subsequent siblings)
12 siblings, 1 reply; 25+ messages in thread
From: Sanjay Chitroda via B4 Relay @ 2026-08-06 12:25 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Jiri Kosina, Srinivas Pandruvada, Benjamin Tissoires
Cc: linux-iio, linux-kernel, linux-input, Sanjay Chitroda, Zhang Lixu
From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
hid_sensor_remove_trigger() no longer uses the iio_dev argument.
Remove the unused argument from all HID IIO drivers to match
updated function prototype.
Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Tested-by: Zhang Lixu <lixu.zhang@intel.com>
---
changes in v4:
- Rectify commit message with input from David
---
drivers/iio/accel/hid-sensor-accel-3d.c | 4 ++--
drivers/iio/common/hid-sensors/hid-sensor-trigger.c | 3 +--
drivers/iio/common/hid-sensors/hid-sensor-trigger.h | 3 +--
drivers/iio/gyro/hid-sensor-gyro-3d.c | 4 ++--
drivers/iio/humidity/hid-sensor-humidity.c | 4 ++--
drivers/iio/light/hid-sensor-als.c | 4 ++--
drivers/iio/light/hid-sensor-prox.c | 4 ++--
drivers/iio/magnetometer/hid-sensor-magn-3d.c | 4 ++--
drivers/iio/orientation/hid-sensor-incl-3d.c | 4 ++--
drivers/iio/orientation/hid-sensor-rotation.c | 4 ++--
drivers/iio/position/hid-sensor-custom-intel-hinge.c | 4 ++--
drivers/iio/pressure/hid-sensor-press.c | 4 ++--
drivers/iio/temperature/hid-sensor-temperature.c | 4 ++--
13 files changed, 24 insertions(+), 26 deletions(-)
diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c
index eb521125f4eb..a7cccbaa82f8 100644
--- a/drivers/iio/accel/hid-sensor-accel-3d.c
+++ b/drivers/iio/accel/hid-sensor-accel-3d.c
@@ -402,7 +402,7 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
error_remove_callback:
sensor_hub_remove_callback(hsdev, hsdev->usage);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev, &accel_state->common_attributes);
+ hid_sensor_remove_trigger(&accel_state->common_attributes);
return ret;
}
@@ -415,7 +415,7 @@ static void hid_accel_3d_remove(struct platform_device *pdev)
iio_device_unregister(indio_dev);
sensor_hub_remove_callback(hsdev, hsdev->usage);
- hid_sensor_remove_trigger(indio_dev, &accel_state->common_attributes);
+ hid_sensor_remove_trigger(&accel_state->common_attributes);
}
static const struct platform_device_id hid_accel_3d_ids[] = {
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
index 60808e2430ca..6e6adc501602 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
@@ -218,8 +218,7 @@ static const struct iio_buffer_setup_ops hid_sensor_buffer_ops = {
.predisable = buffer_predisable,
};
-void hid_sensor_remove_trigger(struct iio_dev *indio_dev,
- struct hid_sensor_common *attrb)
+void hid_sensor_remove_trigger(struct hid_sensor_common *attrb)
{
if (atomic_read(&attrb->runtime_pm_enable))
pm_runtime_disable(&attrb->pdev->dev);
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.h b/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
index 589de858e369..ee17d5cc2437 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
+++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
@@ -16,8 +16,7 @@ extern const struct dev_pm_ops hid_sensor_pm_ops;
int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
struct hid_sensor_common *attrb);
-void hid_sensor_remove_trigger(struct iio_dev *indio_dev,
- struct hid_sensor_common *attrb);
+void hid_sensor_remove_trigger(struct hid_sensor_common *attrb);
int hid_sensor_power_state(struct hid_sensor_common *st, bool state);
#endif
diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c
index 58250a972567..cf049700d415 100644
--- a/drivers/iio/gyro/hid-sensor-gyro-3d.c
+++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c
@@ -339,7 +339,7 @@ static int hid_gyro_3d_probe(struct platform_device *pdev)
error_remove_callback:
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_GYRO_3D);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev, &gyro_state->common_attributes);
+ hid_sensor_remove_trigger(&gyro_state->common_attributes);
return ret;
}
@@ -352,7 +352,7 @@ static void hid_gyro_3d_remove(struct platform_device *pdev)
iio_device_unregister(indio_dev);
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_GYRO_3D);
- hid_sensor_remove_trigger(indio_dev, &gyro_state->common_attributes);
+ hid_sensor_remove_trigger(&gyro_state->common_attributes);
}
static const struct platform_device_id hid_gyro_3d_ids[] = {
diff --git a/drivers/iio/humidity/hid-sensor-humidity.c b/drivers/iio/humidity/hid-sensor-humidity.c
index 7cec81ff5685..89daf9d534d1 100644
--- a/drivers/iio/humidity/hid-sensor-humidity.c
+++ b/drivers/iio/humidity/hid-sensor-humidity.c
@@ -255,7 +255,7 @@ static int hid_humidity_probe(struct platform_device *pdev)
error_remove_callback:
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_HUMIDITY);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev, &humid_st->common_attributes);
+ hid_sensor_remove_trigger(&humid_st->common_attributes);
return ret;
}
@@ -268,7 +268,7 @@ static void hid_humidity_remove(struct platform_device *pdev)
iio_device_unregister(indio_dev);
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_HUMIDITY);
- hid_sensor_remove_trigger(indio_dev, &humid_st->common_attributes);
+ hid_sensor_remove_trigger(&humid_st->common_attributes);
}
static const struct platform_device_id hid_humidity_ids[] = {
diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c
index 929343e42d83..10bf46ea4f47 100644
--- a/drivers/iio/light/hid-sensor-als.c
+++ b/drivers/iio/light/hid-sensor-als.c
@@ -423,7 +423,7 @@ static int hid_als_probe(struct platform_device *pdev)
error_remove_callback:
sensor_hub_remove_callback(hsdev, hsdev->usage);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev, &als_state->common_attributes);
+ hid_sensor_remove_trigger(&als_state->common_attributes);
return ret;
}
@@ -436,7 +436,7 @@ static void hid_als_remove(struct platform_device *pdev)
iio_device_unregister(indio_dev);
sensor_hub_remove_callback(hsdev, hsdev->usage);
- hid_sensor_remove_trigger(indio_dev, &als_state->common_attributes);
+ hid_sensor_remove_trigger(&als_state->common_attributes);
}
static const struct platform_device_id hid_als_ids[] = {
diff --git a/drivers/iio/light/hid-sensor-prox.c b/drivers/iio/light/hid-sensor-prox.c
index 63fd3eff171c..5e28f9b7f40a 100644
--- a/drivers/iio/light/hid-sensor-prox.c
+++ b/drivers/iio/light/hid-sensor-prox.c
@@ -327,7 +327,7 @@ static int hid_prox_probe(struct platform_device *pdev)
error_remove_callback:
sensor_hub_remove_callback(hsdev, hsdev->usage);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev, &prox_state->common_attributes);
+ hid_sensor_remove_trigger(&prox_state->common_attributes);
return ret;
}
@@ -340,7 +340,7 @@ static void hid_prox_remove(struct platform_device *pdev)
iio_device_unregister(indio_dev);
sensor_hub_remove_callback(hsdev, hsdev->usage);
- hid_sensor_remove_trigger(indio_dev, &prox_state->common_attributes);
+ hid_sensor_remove_trigger(&prox_state->common_attributes);
}
static const struct platform_device_id hid_prox_ids[] = {
diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index ad18f233ee16..5402cffa8326 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -526,7 +526,7 @@ static int hid_magn_3d_probe(struct platform_device *pdev)
error_remove_callback:
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_COMPASS_3D);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev, &magn_state->magn_flux_attributes);
+ hid_sensor_remove_trigger(&magn_state->magn_flux_attributes);
return ret;
}
@@ -539,7 +539,7 @@ static void hid_magn_3d_remove(struct platform_device *pdev)
iio_device_unregister(indio_dev);
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_COMPASS_3D);
- hid_sensor_remove_trigger(indio_dev, &magn_state->magn_flux_attributes);
+ hid_sensor_remove_trigger(&magn_state->magn_flux_attributes);
}
static const struct platform_device_id hid_magn_3d_ids[] = {
diff --git a/drivers/iio/orientation/hid-sensor-incl-3d.c b/drivers/iio/orientation/hid-sensor-incl-3d.c
index aea28321db95..435e70557721 100644
--- a/drivers/iio/orientation/hid-sensor-incl-3d.c
+++ b/drivers/iio/orientation/hid-sensor-incl-3d.c
@@ -372,7 +372,7 @@ static int hid_incl_3d_probe(struct platform_device *pdev)
error_remove_callback:
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_INCLINOMETER_3D);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev, &incl_state->common_attributes);
+ hid_sensor_remove_trigger(&incl_state->common_attributes);
return ret;
}
@@ -385,7 +385,7 @@ static void hid_incl_3d_remove(struct platform_device *pdev)
iio_device_unregister(indio_dev);
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_INCLINOMETER_3D);
- hid_sensor_remove_trigger(indio_dev, &incl_state->common_attributes);
+ hid_sensor_remove_trigger(&incl_state->common_attributes);
}
static const struct platform_device_id hid_incl_3d_ids[] = {
diff --git a/drivers/iio/orientation/hid-sensor-rotation.c b/drivers/iio/orientation/hid-sensor-rotation.c
index 9e13a0ecd584..67ffa4f4075e 100644
--- a/drivers/iio/orientation/hid-sensor-rotation.c
+++ b/drivers/iio/orientation/hid-sensor-rotation.c
@@ -348,7 +348,7 @@ static int hid_dev_rot_probe(struct platform_device *pdev)
error_remove_callback:
sensor_hub_remove_callback(hsdev, hsdev->usage);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev, &rot_state->common_attributes);
+ hid_sensor_remove_trigger(&rot_state->common_attributes);
return ret;
}
@@ -361,7 +361,7 @@ static void hid_dev_rot_remove(struct platform_device *pdev)
iio_device_unregister(indio_dev);
sensor_hub_remove_callback(hsdev, hsdev->usage);
- hid_sensor_remove_trigger(indio_dev, &rot_state->common_attributes);
+ hid_sensor_remove_trigger(&rot_state->common_attributes);
}
static const struct platform_device_id hid_dev_rot_ids[] = {
diff --git a/drivers/iio/position/hid-sensor-custom-intel-hinge.c b/drivers/iio/position/hid-sensor-custom-intel-hinge.c
index d275bc1413fe..7f6186fea004 100644
--- a/drivers/iio/position/hid-sensor-custom-intel-hinge.c
+++ b/drivers/iio/position/hid-sensor-custom-intel-hinge.c
@@ -337,7 +337,7 @@ static int hid_hinge_probe(struct platform_device *pdev)
error_remove_callback:
sensor_hub_remove_callback(hsdev, hsdev->usage);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev, &st->common_attributes);
+ hid_sensor_remove_trigger(&st->common_attributes);
return ret;
}
@@ -350,7 +350,7 @@ static void hid_hinge_remove(struct platform_device *pdev)
iio_device_unregister(indio_dev);
sensor_hub_remove_callback(hsdev, hsdev->usage);
- hid_sensor_remove_trigger(indio_dev, &st->common_attributes);
+ hid_sensor_remove_trigger(&st->common_attributes);
}
static const struct platform_device_id hid_hinge_ids[] = {
diff --git a/drivers/iio/pressure/hid-sensor-press.c b/drivers/iio/pressure/hid-sensor-press.c
index e688b0776547..4e0f42fefd6b 100644
--- a/drivers/iio/pressure/hid-sensor-press.c
+++ b/drivers/iio/pressure/hid-sensor-press.c
@@ -306,7 +306,7 @@ static int hid_press_probe(struct platform_device *pdev)
error_remove_callback:
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_PRESSURE);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev, &press_state->common_attributes);
+ hid_sensor_remove_trigger(&press_state->common_attributes);
return ret;
}
@@ -319,7 +319,7 @@ static void hid_press_remove(struct platform_device *pdev)
iio_device_unregister(indio_dev);
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_PRESSURE);
- hid_sensor_remove_trigger(indio_dev, &press_state->common_attributes);
+ hid_sensor_remove_trigger(&press_state->common_attributes);
}
static const struct platform_device_id hid_press_ids[] = {
diff --git a/drivers/iio/temperature/hid-sensor-temperature.c b/drivers/iio/temperature/hid-sensor-temperature.c
index 76723176d6b6..ddd61cf505f1 100644
--- a/drivers/iio/temperature/hid-sensor-temperature.c
+++ b/drivers/iio/temperature/hid-sensor-temperature.c
@@ -252,7 +252,7 @@ static int hid_temperature_probe(struct platform_device *pdev)
error_remove_callback:
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TEMPERATURE);
error_remove_trigger:
- hid_sensor_remove_trigger(indio_dev, &temp_st->common_attributes);
+ hid_sensor_remove_trigger(&temp_st->common_attributes);
return ret;
}
@@ -264,7 +264,7 @@ static void hid_temperature_remove(struct platform_device *pdev)
struct temperature_state *temp_st = iio_priv(indio_dev);
sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TEMPERATURE);
- hid_sensor_remove_trigger(indio_dev, &temp_st->common_attributes);
+ hid_sensor_remove_trigger(&temp_st->common_attributes);
}
static const struct platform_device_id hid_temperature_ids[] = {
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* Re: [PATCH v5 01/13] iio: hid-sensors: remove unused iio_dev argument
2026-08-06 12:25 ` [PATCH v5 01/13] iio: hid-sensors: remove unused iio_dev argument Sanjay Chitroda via B4 Relay
@ 2026-08-06 12:37 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-08-06 12:37 UTC (permalink / raw)
To: Sanjay Chitroda; +Cc: dmitry.torokhov, linux-input
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Concurrent execution of `sensor_hub_raw_event` and a child IIO driver's `remove` function can cause a Use-After-Free on the IIO device state.
--
--- Patch [1]: [PATCH v5 01/13] iio: hid-sensors: remove unused iio_dev argument ---
commit c12a28d854a2931313f7d217face266eaf20a33a
Author: Sanjay Chitroda <sanjayembeddedse@gmail.com>
iio: hid-sensors: remove unused iio_dev argument
hid_sensor_remove_trigger() no longer uses the iio_dev argument. Remove the
unused argument from all HID IIO drivers to match updated function prototype.
> diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c
> --- a/drivers/iio/accel/hid-sensor-accel-3d.c
> +++ b/drivers/iio/accel/hid-sensor-accel-3d.c
[ ... ]
> @@ -415,7 +415,7 @@ static void hid_accel_3d_remove(struct platform_device *pdev)
>
> iio_device_unregister(indio_dev);
> sensor_hub_remove_callback(hsdev, hsdev->usage);
[Severity: High]
This isn't a bug introduced by this patch, but does the concurrent execution
of sensor_hub_raw_event() and this remove() function cause a use-after-free
on the IIO device state?
Looking at sensor_hub_remove_callback() in drivers/hid/hid-sensor-hub.c, it
removes the callback using dyn_callback_lock but does not synchronize with
pdata->lock:
drivers/hid/hid-sensor-hub.c:sensor_hub_remove_callback() {
spin_lock_irqsave(&pdata->dyn_callback_lock, flags);
// list removal
spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
}
If an unbind happens concurrently with an incoming hardware event:
CPU1
sensor_hub_raw_event()
acquires pdata->lock
finds registered callback
CPU2
hid_accel_3d_remove()
sensor_hub_remove_callback()
removes callback and returns
devres framework frees the IIO device state
CPU1
sensor_hub_raw_event()
if (callback->capture_sample) {
callback->capture_sample(...) // Dereferences freed IIO state
Can this lead to memory corruption during physical device removal or sysfs
unbind?
> - hid_sensor_remove_trigger(indio_dev, &accel_state->common_attributes);
> + hid_sensor_remove_trigger(&accel_state->common_attributes);
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260806-28-apr-iio-redundant-argument-v5-temp-v5-0-f1f92c1d830f@gmail.com?part=1
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v5 02/13] iio: hid-sensors: introduce device managed API
2026-08-06 12:25 [PATCH v5 00/13] HID: iio: Introduce devm_ APIs for HID sensors Sanjay Chitroda via B4 Relay
2026-08-06 12:25 ` [PATCH v5 01/13] iio: hid-sensors: remove unused iio_dev argument Sanjay Chitroda via B4 Relay
@ 2026-08-06 12:25 ` Sanjay Chitroda via B4 Relay
2026-08-06 12:25 ` [PATCH v5 03/13] HID: hid-sensor-hub: " Sanjay Chitroda via B4 Relay
` (10 subsequent siblings)
12 siblings, 0 replies; 25+ messages in thread
From: Sanjay Chitroda via B4 Relay @ 2026-08-06 12:25 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Jiri Kosina, Srinivas Pandruvada, Benjamin Tissoires
Cc: linux-iio, linux-kernel, linux-input, Sanjay Chitroda, Zhang Lixu
From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
hid_sensor_setup_trigger() is common API used for the HID IIO drivers,
prepare devm API devm_hid_sensor_setup_trigger() to acquire resource
during setup and release using device managed framework during drivers
fail, unbind or remove path.
Register action with devm_add_action_or_reset() to release resource with
devres framework.
Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Tested-by: Zhang Lixu <lixu.zhang@intel.com>
---
drivers/iio/common/hid-sensors/hid-sensor-trigger.c | 18 ++++++++++++++++++
drivers/iio/common/hid-sensors/hid-sensor-trigger.h | 2 ++
2 files changed, 20 insertions(+)
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
index 6e6adc501602..df6c07d6a6b7 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
@@ -301,6 +301,24 @@ int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
}
EXPORT_SYMBOL_NS(hid_sensor_setup_trigger, "IIO_HID");
+static void hid_sensor_remove_trigger_action(void *attrb)
+{
+ hid_sensor_remove_trigger(attrb);
+}
+
+int devm_hid_sensor_setup_trigger(struct device *dev, struct iio_dev *indio_dev,
+ const char *name, struct hid_sensor_common *attrb)
+{
+ int ret;
+
+ ret = hid_sensor_setup_trigger(indio_dev, name, attrb);
+ if (ret)
+ return ret;
+
+ return devm_add_action_or_reset(dev, hid_sensor_remove_trigger_action, attrb);
+}
+EXPORT_SYMBOL_NS(devm_hid_sensor_setup_trigger, "IIO_HID");
+
static int __maybe_unused hid_sensor_suspend(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.h b/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
index ee17d5cc2437..c4b901ca4879 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
+++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
@@ -17,6 +17,8 @@ extern const struct dev_pm_ops hid_sensor_pm_ops;
int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
struct hid_sensor_common *attrb);
void hid_sensor_remove_trigger(struct hid_sensor_common *attrb);
+int devm_hid_sensor_setup_trigger(struct device *dev, struct iio_dev *indio_dev,
+ const char *name, struct hid_sensor_common *attrb);
int hid_sensor_power_state(struct hid_sensor_common *st, bool state);
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* [PATCH v5 03/13] HID: hid-sensor-hub: introduce device managed API
2026-08-06 12:25 [PATCH v5 00/13] HID: iio: Introduce devm_ APIs for HID sensors Sanjay Chitroda via B4 Relay
2026-08-06 12:25 ` [PATCH v5 01/13] iio: hid-sensors: remove unused iio_dev argument Sanjay Chitroda via B4 Relay
2026-08-06 12:25 ` [PATCH v5 02/13] iio: hid-sensors: introduce device managed API Sanjay Chitroda via B4 Relay
@ 2026-08-06 12:25 ` Sanjay Chitroda via B4 Relay
2026-08-06 12:40 ` sashiko-bot
2026-08-08 20:10 ` Andy Shevchenko
2026-08-06 12:25 ` [PATCH v5 04/13] iio: gyro: hid-sensor-gyro-3d: convert probe and teardown to devm-managed resources Sanjay Chitroda via B4 Relay
` (9 subsequent siblings)
12 siblings, 2 replies; 25+ messages in thread
From: Sanjay Chitroda via B4 Relay @ 2026-08-06 12:25 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Jiri Kosina, Srinivas Pandruvada, Benjamin Tissoires
Cc: linux-iio, linux-kernel, linux-input, Sanjay Chitroda
From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
sensor_hub_register_callback() is common API used for the HID IIO drivers,
prepare devm API devm_sensor_hub_register_callback() to acquire resource
during setup and release using device managed framework during drivers
fail, unbind or remove path.
store the required callback removal context (hsdev and usage_id) in a
dedicated struct sensor_hub_cb_devres, and register a devres action to
handle to release resource with devres framework and helper API.
Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
drivers/hid/hid-sensor-hub.c | 32 ++++++++++++++++++++++++++++++++
include/linux/hid-sensor-hub.h | 24 ++++++++++++++++++++++++
2 files changed, 56 insertions(+)
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
index 90666ff629de..31dbdce27dc6 100644
--- a/drivers/hid/hid-sensor-hub.c
+++ b/drivers/hid/hid-sensor-hub.c
@@ -187,6 +187,38 @@ int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev,
}
EXPORT_SYMBOL_GPL(sensor_hub_remove_callback);
+static void sensor_hub_remove_callback_helper(void *ptr)
+{
+ struct sensor_hub_cb_devres *res = ptr;
+
+ sensor_hub_remove_callback(res->hsdev, res->usage_id);
+}
+
+int devm_sensor_hub_register_callback(struct device *dev,
+ struct hid_sensor_hub_device *hsdev,
+ u32 usage_id,
+ struct hid_sensor_hub_callbacks *usage_callback)
+{
+ struct sensor_hub_cb_devres *res;
+ int ret;
+
+ ret = sensor_hub_register_callback(hsdev, usage_id, usage_callback);
+ if (ret)
+ return ret;
+
+ res = devm_kmalloc(dev, sizeof(*res), GFP_KERNEL);
+ if (!res) {
+ sensor_hub_remove_callback(hsdev, usage_id);
+ return -ENOMEM;
+ }
+
+ res->hsdev = hsdev;
+ res->usage_id = usage_id;
+
+ return devm_add_action_or_reset(dev, sensor_hub_remove_callback_helper, res);
+}
+EXPORT_SYMBOL_GPL(devm_sensor_hub_register_callback);
+
int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
u32 field_index, int buffer_size, void *buffer)
{
diff --git a/include/linux/hid-sensor-hub.h b/include/linux/hid-sensor-hub.h
index e71056553108..c00347b15513 100644
--- a/include/linux/hid-sensor-hub.h
+++ b/include/linux/hid-sensor-hub.h
@@ -75,6 +75,16 @@ struct hid_sensor_hub_device {
struct sensor_hub_pending pending;
};
+/**
+ * struct sensor_hub_cb_devres - devres data for sensor hub callbacks
+ * @hsdev: Hub device instance.
+ * @usage_id: Usage ID associated with registered callback
+ */
+struct sensor_hub_cb_devres {
+ struct hid_sensor_hub_device *hsdev;
+ u32 usage_id;
+};
+
/**
* struct hid_sensor_hub_callbacks - Client callback functions
* @pdev: Platform device instance of the client driver.
@@ -139,6 +149,20 @@ int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev,
int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev,
u32 usage_id);
+/**
+ * devm_sensor_hub_register_callback() - Managed register client callbacks
+ * @dev: Device for resource management
+ * @hsdev: Hub device instance
+ * @usage_id: Usage id of the client (e.g. 0x200076 for Gyro)
+ * @usage_callback: Callback function storage
+ *
+ * This is the devres (managed) version of sensor_hub_register_callback().
+ * The callback will be automatically unregistered when the device is detached.
+ */
+int devm_sensor_hub_register_callback(struct device *dev,
+ struct hid_sensor_hub_device *hsdev,
+ u32 usage_id,
+ struct hid_sensor_hub_callbacks *usage_callback);
/* Hid sensor hub core interfaces */
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* Re: [PATCH v5 03/13] HID: hid-sensor-hub: introduce device managed API
2026-08-06 12:25 ` [PATCH v5 03/13] HID: hid-sensor-hub: " Sanjay Chitroda via B4 Relay
@ 2026-08-06 12:40 ` sashiko-bot
2026-08-08 20:10 ` Andy Shevchenko
1 sibling, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-08-06 12:40 UTC (permalink / raw)
To: Sanjay Chitroda; +Cc: dmitry.torokhov, linux-input
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Lack of synchronization in `sensor_hub_remove_callback` allows `sensor_hub_raw_event` to access a freed `usage_callback` during driver unbind.
--
--- Patch [3]: [PATCH v5 03/13] HID: hid-sensor-hub: introduce device managed API ---
commit 1f72201981d4eabf709dd34d77a678b2f0acfcf2
Author: Sanjay Chitroda <sanjayembeddedse@gmail.com>
HID: hid-sensor-hub: introduce device managed API
This commit introduces devm_sensor_hub_register_callback() to handle
resource acquisition and release using the device managed framework. It
adds a devres action that automatically unregisters the sensor hub
callback when the device is detached or unbound.
> diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
> --- a/drivers/hid/hid-sensor-hub.c
> +++ b/drivers/hid/hid-sensor-hub.c
[ ... ]
> @@ -187,6 +187,38 @@ int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev,
> }
> EXPORT_SYMBOL_GPL(sensor_hub_remove_callback);
>
> +static void sensor_hub_remove_callback_helper(void *ptr)
> +{
> + struct sensor_hub_cb_devres *res = ptr;
> +
> + sensor_hub_remove_callback(res->hsdev, res->usage_id);
> +}
[Severity: High]
This isn't a bug introduced by this patch, but does
sensor_hub_remove_callback() lack synchronization with ongoing raw events?
When a client driver is unbound via sysfs, this helper will call
sensor_hub_remove_callback() to clean up. While the remove function
acquires pdata->dyn_callback_lock to unlink the callback, it returns
immediately without acquiring pdata->lock.
This means it does not wait for ongoing events to finish:
drivers/hid/hid-sensor-hub.c:sensor_hub_remove_callback() {
spin_lock_irqsave(&pdata->dyn_callback_lock, flags);
// unlinks callback
spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
return 0;
}
Meanwhile, sensor_hub_raw_event() can be actively executing on another CPU,
having already dropped dyn_callback_lock:
drivers/hid/hid-sensor-hub.c:sensor_hub_raw_event() {
...
callback->capture_sample(hsdev, ...);
...
}
Because the unbind process continues immediately after the removal returns,
it can free the memory containing the usage_callback (such as through
devres_release_all()).
Could this lead to a use-after-free in sensor_hub_raw_event() when it
dereferences the freed callback pointer?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260806-28-apr-iio-redundant-argument-v5-temp-v5-0-f1f92c1d830f@gmail.com?part=3
^ permalink raw reply [flat|nested] 25+ messages in thread* Re: [PATCH v5 03/13] HID: hid-sensor-hub: introduce device managed API
2026-08-06 12:25 ` [PATCH v5 03/13] HID: hid-sensor-hub: " Sanjay Chitroda via B4 Relay
2026-08-06 12:40 ` sashiko-bot
@ 2026-08-08 20:10 ` Andy Shevchenko
1 sibling, 0 replies; 25+ messages in thread
From: Andy Shevchenko @ 2026-08-08 20:10 UTC (permalink / raw)
To: sanjayembeddedse
Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Jiri Kosina, Srinivas Pandruvada, Benjamin Tissoires, linux-iio,
linux-kernel, linux-input
On Thu, Aug 06, 2026 at 05:55:49PM +0530, Sanjay Chitroda via B4 Relay wrote:
> sensor_hub_register_callback() is common API used for the HID IIO drivers,
> prepare devm API devm_sensor_hub_register_callback() to acquire resource
> during setup and release using device managed framework during drivers
> fail, unbind or remove path.
>
> store the required callback removal context (hsdev and usage_id) in a
Store
> dedicated struct sensor_hub_cb_devres, and register a devres action to
> handle to release resource with devres framework and helper API.
...
> +static void sensor_hub_remove_callback_helper(void *ptr)
> +{
> + struct sensor_hub_cb_devres *res = ptr;
> +
> + sensor_hub_remove_callback(res->hsdev, res->usage_id);
> +}
> +
> +int devm_sensor_hub_register_callback(struct device *dev,
> + struct hid_sensor_hub_device *hsdev,
> + u32 usage_id,
> + struct hid_sensor_hub_callbacks *usage_callback)
> +{
> + struct sensor_hub_cb_devres *res;
> + int ret;
> +
> + ret = sensor_hub_register_callback(hsdev, usage_id, usage_callback);
> + if (ret)
> + return ret;
> +
> + res = devm_kmalloc(dev, sizeof(*res), GFP_KERNEL);
> + if (!res) {
> + sensor_hub_remove_callback(hsdev, usage_id);
> + return -ENOMEM;
> + }
Why is this order? What's wrong with the memory allocation first?
> + res->hsdev = hsdev;
> + res->usage_id = usage_id;
> +
> + return devm_add_action_or_reset(dev, sensor_hub_remove_callback_helper, res);
> +}
...
> +/**
> + * devm_sensor_hub_register_callback() - Managed register client callbacks
> + * @dev: Device for resource management
> + * @hsdev: Hub device instance
> + * @usage_id: Usage id of the client (e.g. 0x200076 for Gyro)
> + * @usage_callback: Callback function storage
> + *
> + * This is the devres (managed) version of sensor_hub_register_callback().
> + * The callback will be automatically unregistered when the device is detached.
Here, and everywhere else, validate kernel-doc. Here you introduced a new warning
(missing return section).
> + */
Also, why kernel-doc is here?! It should accompany the implementation, here is
a declaration.
> +int devm_sensor_hub_register_callback(struct device *dev,
> + struct hid_sensor_hub_device *hsdev,
> + u32 usage_id,
> + struct hid_sensor_hub_callbacks *usage_callback);
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v5 04/13] iio: gyro: hid-sensor-gyro-3d: convert probe and teardown to devm-managed resources
2026-08-06 12:25 [PATCH v5 00/13] HID: iio: Introduce devm_ APIs for HID sensors Sanjay Chitroda via B4 Relay
` (2 preceding siblings ...)
2026-08-06 12:25 ` [PATCH v5 03/13] HID: hid-sensor-hub: " Sanjay Chitroda via B4 Relay
@ 2026-08-06 12:25 ` Sanjay Chitroda via B4 Relay
2026-08-06 12:40 ` sashiko-bot
2026-08-06 12:25 ` [PATCH v5 05/13] iio: accel: hid-sensor-accel-3d: " Sanjay Chitroda via B4 Relay
` (8 subsequent siblings)
12 siblings, 1 reply; 25+ messages in thread
From: Sanjay Chitroda via B4 Relay @ 2026-08-06 12:25 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Jiri Kosina, Srinivas Pandruvada, Benjamin Tissoires
Cc: linux-iio, linux-kernel, linux-input, Sanjay Chitroda
From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Convert HID IIO driver resource management to use devm-managed helpers,
tying the lifetime of all resources to the device.
HID trigger setup, IIO registration, and sensor hub callback resource
are now managed using devm APIs. Cleanup logic previously handled
explicitly in probe error and teardown paths.
This simplifies the probe path by removing goto-based error handling,
eliminates the remove callback entirely.
Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
drivers/iio/gyro/hid-sensor-gyro-3d.c | 41 ++++++++---------------------------
1 file changed, 9 insertions(+), 32 deletions(-)
diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c
index cf049700d415..66778315e86d 100644
--- a/drivers/iio/gyro/hid-sensor-gyro-3d.c
+++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c
@@ -264,7 +264,8 @@ static int gyro_3d_parse_report(struct platform_device *pdev,
/* Function to initialize the processing for usage id */
static int hid_gyro_3d_probe(struct platform_device *pdev)
{
- struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
+ struct device *dev = &pdev->dev;
+ struct hid_sensor_hub_device *hsdev = dev_get_platdata(dev);
int ret = 0;
static const char *name = "gyro_3d";
struct iio_dev *indio_dev;
@@ -311,8 +312,8 @@ static int hid_gyro_3d_probe(struct platform_device *pdev)
atomic_set(&gyro_state->common_attributes.data_ready, 0);
- ret = hid_sensor_setup_trigger(indio_dev, name,
- &gyro_state->common_attributes);
+ ret = devm_hid_sensor_setup_trigger(dev, indio_dev, name,
+ &gyro_state->common_attributes);
if (ret < 0) {
dev_err(&pdev->dev, "trigger setup failed\n");
return ret;
@@ -321,38 +322,15 @@ static int hid_gyro_3d_probe(struct platform_device *pdev)
gyro_state->callbacks.send_event = gyro_3d_proc_event;
gyro_state->callbacks.capture_sample = gyro_3d_capture_sample;
gyro_state->callbacks.pdev = pdev;
- ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_GYRO_3D,
- &gyro_state->callbacks);
+ ret = devm_sensor_hub_register_callback(dev, hsdev,
+ HID_USAGE_SENSOR_GYRO_3D,
+ &gyro_state->callbacks);
if (ret < 0) {
dev_err(&pdev->dev, "callback reg failed\n");
- goto error_remove_trigger;
- }
-
- ret = iio_device_register(indio_dev);
- if (ret) {
- dev_err(&pdev->dev, "device register failed\n");
- goto error_remove_callback;
+ return ret;
}
- return ret;
-
-error_remove_callback:
- sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_GYRO_3D);
-error_remove_trigger:
- hid_sensor_remove_trigger(&gyro_state->common_attributes);
- return ret;
-}
-
-/* Function to deinitialize the processing for usage id */
-static void hid_gyro_3d_remove(struct platform_device *pdev)
-{
- struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
- struct iio_dev *indio_dev = platform_get_drvdata(pdev);
- struct gyro_3d_state *gyro_state = iio_priv(indio_dev);
-
- iio_device_unregister(indio_dev);
- sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_GYRO_3D);
- hid_sensor_remove_trigger(&gyro_state->common_attributes);
+ return devm_iio_device_register(dev, indio_dev);
}
static const struct platform_device_id hid_gyro_3d_ids[] = {
@@ -371,7 +349,6 @@ static struct platform_driver hid_gyro_3d_platform_driver = {
.pm = &hid_sensor_pm_ops,
},
.probe = hid_gyro_3d_probe,
- .remove = hid_gyro_3d_remove,
};
module_platform_driver(hid_gyro_3d_platform_driver);
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* Re: [PATCH v5 04/13] iio: gyro: hid-sensor-gyro-3d: convert probe and teardown to devm-managed resources
2026-08-06 12:25 ` [PATCH v5 04/13] iio: gyro: hid-sensor-gyro-3d: convert probe and teardown to devm-managed resources Sanjay Chitroda via B4 Relay
@ 2026-08-06 12:40 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-08-06 12:40 UTC (permalink / raw)
To: Sanjay Chitroda; +Cc: dmitry.torokhov, linux-input
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Preexisting UAF race between HID sensor event delivery and device unbinding.
--
--- Patch [4]: [PATCH v5 04/13] iio: gyro: hid-sensor-gyro-3d: convert probe and teardown to devm-managed resources ---
Note: The format of this report is altered due to recitation restrictions. The original patch diff is not quoted.
commit 0412f8ea67eb98e8cb4da48580ccc04772e8482a
Author: Sanjay Chitroda <sanjayembeddedse@gmail.com>
iio: gyro: hid-sensor-gyro-3d: convert probe and teardown to devm-managed resources
Convert HID IIO driver resource management to use devm-managed helpers,
tying the lifetime of all resources to the device. This simplifies the
probe path by removing goto-based error handling and eliminates the
remove callback entirely.
[Severity: High]
This is a pre-existing issue, but I noticed a potential Use-After-Free race
between HID sensor event delivery and device unbinding that could be exposed
here.
In drivers/hid/hid-sensor-hub.c:sensor_hub_remove_callback(), the callback
is removed from the list while holding dyn_callback_lock, but the function
returns immediately without synchronizing with or waiting for concurrent
readers to finish.
If a concurrent event is being processed in sensor_hub_raw_event(), it drops
dyn_callback_lock before invoking callback->capture_sample and accessing
callback->pdev.
During device unbind, the devres cleanup for the newly introduced
devm_sensor_hub_register_callback() will remove the callback. Immediately
after, the devres cleanup for devm_iio_device_alloc() frees indio_dev,
which contains the gyro_state->callbacks structure.
If sensor_hub_raw_event() is executing concurrently with an unbind (for
example, via sysfs), could it dereference the freed callback pointer to call
callback->capture_sample, leading to a Use-After-Free?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260806-28-apr-iio-redundant-argument-v5-temp-v5-0-f1f92c1d830f@gmail.com?part=4
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v5 05/13] iio: accel: hid-sensor-accel-3d: convert probe and teardown to devm-managed resources
2026-08-06 12:25 [PATCH v5 00/13] HID: iio: Introduce devm_ APIs for HID sensors Sanjay Chitroda via B4 Relay
` (3 preceding siblings ...)
2026-08-06 12:25 ` [PATCH v5 04/13] iio: gyro: hid-sensor-gyro-3d: convert probe and teardown to devm-managed resources Sanjay Chitroda via B4 Relay
@ 2026-08-06 12:25 ` Sanjay Chitroda via B4 Relay
2026-08-06 12:39 ` sashiko-bot
2026-08-06 12:25 ` [PATCH v5 06/13] iio: humidity: hid-sensor-humidity: " Sanjay Chitroda via B4 Relay
` (7 subsequent siblings)
12 siblings, 1 reply; 25+ messages in thread
From: Sanjay Chitroda via B4 Relay @ 2026-08-06 12:25 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Jiri Kosina, Srinivas Pandruvada, Benjamin Tissoires
Cc: linux-iio, linux-kernel, linux-input, Sanjay Chitroda
From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Convert HID IIO driver resource management to use devm-managed helpers,
tying the lifetime of all resources to the device.
HID trigger setup, IIO registration, and sensor hub callback resource
are now managed using devm APIs. Cleanup logic previously handled
explicitly in probe error and teardown paths.
This simplifies the probe path by removing goto-based error handling,
eliminates the remove callback entirely.
Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
drivers/iio/accel/hid-sensor-accel-3d.c | 40 +++++++--------------------------
1 file changed, 8 insertions(+), 32 deletions(-)
diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c
index a7cccbaa82f8..7ba0228f18b4 100644
--- a/drivers/iio/accel/hid-sensor-accel-3d.c
+++ b/drivers/iio/accel/hid-sensor-accel-3d.c
@@ -314,7 +314,8 @@ static int accel_3d_parse_report(struct platform_device *pdev,
/* Function to initialize the processing for usage id */
static int hid_accel_3d_probe(struct platform_device *pdev)
{
- struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
+ struct device *dev = &pdev->dev;
+ struct hid_sensor_hub_device *hsdev = dev_get_platdata(dev);
int ret = 0;
const char *name;
struct iio_dev *indio_dev;
@@ -374,8 +375,8 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
atomic_set(&accel_state->common_attributes.data_ready, 0);
- ret = hid_sensor_setup_trigger(indio_dev, name,
- &accel_state->common_attributes);
+ ret = devm_hid_sensor_setup_trigger(dev, indio_dev, name,
+ &accel_state->common_attributes);
if (ret < 0) {
dev_err(&pdev->dev, "trigger setup failed\n");
return ret;
@@ -384,38 +385,14 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
accel_state->callbacks.send_event = accel_3d_proc_event;
accel_state->callbacks.capture_sample = accel_3d_capture_sample;
accel_state->callbacks.pdev = pdev;
- ret = sensor_hub_register_callback(hsdev, hsdev->usage,
- &accel_state->callbacks);
+ ret = devm_sensor_hub_register_callback(dev, hsdev, hsdev->usage,
+ &accel_state->callbacks);
if (ret < 0) {
dev_err(&pdev->dev, "callback reg failed\n");
- goto error_remove_trigger;
- }
-
- ret = iio_device_register(indio_dev);
- if (ret) {
- dev_err(&pdev->dev, "device register failed\n");
- goto error_remove_callback;
+ return ret;
}
- return ret;
-
-error_remove_callback:
- sensor_hub_remove_callback(hsdev, hsdev->usage);
-error_remove_trigger:
- hid_sensor_remove_trigger(&accel_state->common_attributes);
- return ret;
-}
-
-/* Function to deinitialize the processing for usage id */
-static void hid_accel_3d_remove(struct platform_device *pdev)
-{
- struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
- struct iio_dev *indio_dev = platform_get_drvdata(pdev);
- struct accel_3d_state *accel_state = iio_priv(indio_dev);
-
- iio_device_unregister(indio_dev);
- sensor_hub_remove_callback(hsdev, hsdev->usage);
- hid_sensor_remove_trigger(&accel_state->common_attributes);
+ return devm_iio_device_register(dev, indio_dev);
}
static const struct platform_device_id hid_accel_3d_ids[] = {
@@ -437,7 +414,6 @@ static struct platform_driver hid_accel_3d_platform_driver = {
.pm = &hid_sensor_pm_ops,
},
.probe = hid_accel_3d_probe,
- .remove = hid_accel_3d_remove,
};
module_platform_driver(hid_accel_3d_platform_driver);
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* Re: [PATCH v5 05/13] iio: accel: hid-sensor-accel-3d: convert probe and teardown to devm-managed resources
2026-08-06 12:25 ` [PATCH v5 05/13] iio: accel: hid-sensor-accel-3d: " Sanjay Chitroda via B4 Relay
@ 2026-08-06 12:39 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-08-06 12:39 UTC (permalink / raw)
To: Sanjay Chitroda; +Cc: dmitry.torokhov, linux-input
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [Critical] Concurrent HID sensor events can trigger a Use-After-Free because callback deregistration does not synchronize with active event handlers.
--
--- Patch [5]: [PATCH v5 05/13] iio: accel: hid-sensor-accel-3d: convert probe and teardown to devm-managed resources ---
commit a9b078923d03e5b1bd623e5152abd36454ac1fc5
Author: Sanjay Chitroda <sanjayembeddedse@gmail.com>
iio: accel: hid-sensor-accel-3d: convert probe and teardown to devm-managed resources
Convert HID IIO driver resource management to use devm-managed helpers,
tying the lifetime of all resources to the device.
> diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c
> index a7cccbaa82f86..7ba0228f18b43 100644
> --- a/drivers/iio/accel/hid-sensor-accel-3d.c
> +++ b/drivers/iio/accel/hid-sensor-accel-3d.c
[ ... ]
> @@ -384,38 +385,14 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
> accel_state->callbacks.send_event = accel_3d_proc_event;
> accel_state->callbacks.capture_sample = accel_3d_capture_sample;
> accel_state->callbacks.pdev = pdev;
> - ret = sensor_hub_register_callback(hsdev, hsdev->usage,
> - &accel_state->callbacks);
> + ret = devm_sensor_hub_register_callback(dev, hsdev, hsdev->usage,
> + &accel_state->callbacks);
[Severity: Critical]
This is a pre-existing issue, but does this sequence leave a use-after-free
window during device teardown?
If the driver unbinds or probe fails, devres will call
sensor_hub_remove_callback(). This removes the callback from the list using
dyn_callback_lock, but it does not wait for active sensor_hub_raw_event()
invocations to complete.
If sensor_hub_raw_event() is running concurrently and has already obtained the
callback pointer, devres will proceed to free the indio_dev memory.
When the event loop subsequently invokes the callback, wouldn't
accel_3d_capture_sample() execute on the freed memory?
drivers/hid/hid-sensor-hub.c:sensor_hub_raw_event() {
...
if (callback->capture_sample) {
if (report->field[i]->logical)
callback->capture_sample(...);
...
}
Could this lead to out-of-bounds writes when it attempts to store the
sample data into the freed accel_state?
drivers/iio/accel/hid-sensor-accel-3d.c:accel_3d_capture_sample() {
...
struct iio_dev *indio_dev = platform_get_drvdata(priv);
struct accel_3d_state *accel_state = iio_priv(indio_dev);
...
accel_state->scan.accel_val[CHANNEL_SCAN_INDEX_X + offset] =
*(u32 *)raw_data;
...
}
> if (ret < 0) {
> dev_err(&pdev->dev, "callback reg failed\n");
> - goto error_remove_trigger;
> - }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260806-28-apr-iio-redundant-argument-v5-temp-v5-0-f1f92c1d830f@gmail.com?part=5
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v5 06/13] iio: humidity: hid-sensor-humidity: convert probe and teardown to devm-managed resources
2026-08-06 12:25 [PATCH v5 00/13] HID: iio: Introduce devm_ APIs for HID sensors Sanjay Chitroda via B4 Relay
` (4 preceding siblings ...)
2026-08-06 12:25 ` [PATCH v5 05/13] iio: accel: hid-sensor-accel-3d: " Sanjay Chitroda via B4 Relay
@ 2026-08-06 12:25 ` Sanjay Chitroda via B4 Relay
2026-08-06 12:36 ` sashiko-bot
2026-08-06 12:25 ` [PATCH v5 07/13] iio: light: hid-sensor-prox: " Sanjay Chitroda via B4 Relay
` (6 subsequent siblings)
12 siblings, 1 reply; 25+ messages in thread
From: Sanjay Chitroda via B4 Relay @ 2026-08-06 12:25 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Jiri Kosina, Srinivas Pandruvada, Benjamin Tissoires
Cc: linux-iio, linux-kernel, linux-input, Sanjay Chitroda
From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Convert HID IIO driver resource management to use devm-managed helpers,
tying the lifetime of all resources to the device.
HID trigger setup, IIO registration, and sensor hub callback resource
are now managed using devm APIs. Cleanup logic previously handled
explicitly in probe error and teardown paths.
This simplifies the probe path by removing goto-based error handling,
eliminates the remove callback entirely.
Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
changes in v5:
- Fully convert driver to devm usage, dropped Tested-by tag
changes in v4:
- No update in change, added Tested-by tag
changes in v3:
- Update commit message based on review comment from Andy
- Based on discussion using parent device of HID platform driver used
with devres framework for this driver
- v2 link -> https://lore.kernel.org/all/20260429175918.2541914-5-sanjayembedded@gmail.com/
---
drivers/iio/humidity/hid-sensor-humidity.c | 38 +++++++-----------------------
1 file changed, 8 insertions(+), 30 deletions(-)
diff --git a/drivers/iio/humidity/hid-sensor-humidity.c b/drivers/iio/humidity/hid-sensor-humidity.c
index 89daf9d534d1..12c88efe66be 100644
--- a/drivers/iio/humidity/hid-sensor-humidity.c
+++ b/drivers/iio/humidity/hid-sensor-humidity.c
@@ -192,11 +192,12 @@ static struct hid_sensor_hub_callbacks humidity_callbacks = {
/* Function to initialize the processing for usage id */
static int hid_humidity_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
+ struct hid_sensor_hub_device *hsdev = dev_get_platdata(dev);
static const char *name = "humidity";
struct iio_dev *indio_dev;
struct hid_humidity_state *humid_st;
struct iio_chan_spec *humid_chans;
- struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
int ret;
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*humid_st));
@@ -233,42 +234,20 @@ static int hid_humidity_probe(struct platform_device *pdev)
atomic_set(&humid_st->common_attributes.data_ready, 0);
- ret = hid_sensor_setup_trigger(indio_dev, name,
- &humid_st->common_attributes);
+ ret = devm_hid_sensor_setup_trigger(dev, indio_dev, name,
+ &humid_st->common_attributes);
if (ret)
return ret;
platform_set_drvdata(pdev, indio_dev);
humidity_callbacks.pdev = pdev;
- ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_HUMIDITY,
- &humidity_callbacks);
+ ret = devm_sensor_hub_register_callback(dev, hsdev, HID_USAGE_SENSOR_HUMIDITY,
+ &humidity_callbacks);
if (ret)
- goto error_remove_trigger;
-
- ret = iio_device_register(indio_dev);
- if (ret)
- goto error_remove_callback;
-
- return ret;
-
-error_remove_callback:
- sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_HUMIDITY);
-error_remove_trigger:
- hid_sensor_remove_trigger(&humid_st->common_attributes);
- return ret;
-}
-
-/* Function to deinitialize the processing for usage id */
-static void hid_humidity_remove(struct platform_device *pdev)
-{
- struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
- struct iio_dev *indio_dev = platform_get_drvdata(pdev);
- struct hid_humidity_state *humid_st = iio_priv(indio_dev);
+ return ret;
- iio_device_unregister(indio_dev);
- sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_HUMIDITY);
- hid_sensor_remove_trigger(&humid_st->common_attributes);
+ return devm_iio_device_register(dev, indio_dev);
}
static const struct platform_device_id hid_humidity_ids[] = {
@@ -287,7 +266,6 @@ static struct platform_driver hid_humidity_platform_driver = {
.pm = &hid_sensor_pm_ops,
},
.probe = hid_humidity_probe,
- .remove = hid_humidity_remove,
};
module_platform_driver(hid_humidity_platform_driver);
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* Re: [PATCH v5 06/13] iio: humidity: hid-sensor-humidity: convert probe and teardown to devm-managed resources
2026-08-06 12:25 ` [PATCH v5 06/13] iio: humidity: hid-sensor-humidity: " Sanjay Chitroda via B4 Relay
@ 2026-08-06 12:36 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-08-06 12:36 UTC (permalink / raw)
To: Sanjay Chitroda; +Cc: linux-input, dmitry.torokhov
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Shared global `humidity_callbacks` structure causes `.pdev` pointer overwrite, leading to state corruption and use-after-free when multiple humidity sensors are present.
--
--- Patch [6]: [PATCH v5 06/13] iio: humidity: hid-sensor-humidity: convert probe and teardown to devm-managed resources ---
commit 56374932f747b4eb1a636c154cf264875bcdacc6
Author: Sanjay Chitroda <sanjayembeddedse@gmail.com>
iio: humidity: hid-sensor-humidity: convert probe and teardown to devm-managed resources
This commit converts the HID IIO driver resource management to use
devm-managed helpers. This ties the lifetime of all resources to the
device, simplifies error handling in the probe path, and removes the
explicit remove callback entirely.
> diff --git a/drivers/iio/humidity/hid-sensor-humidity.c b/drivers/iio/humidity/hid-sensor-humidity.c
> --- a/drivers/iio/humidity/hid-sensor-humidity.c
> +++ b/drivers/iio/humidity/hid-sensor-humidity.c
[ ... ]
> @@ -233,42 +234,20 @@ static int hid_humidity_probe(struct platform_device *pdev)
> platform_set_drvdata(pdev, indio_dev);
>
> humidity_callbacks.pdev = pdev;
> - ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_HUMIDITY,
> - &humidity_callbacks);
> + ret = devm_sensor_hub_register_callback(dev, hsdev, HID_USAGE_SENSOR_HUMIDITY,
> + &humidity_callbacks);
[Severity: High]
This is a pre-existing issue, but does assigning pdev to the shared global
humidity_callbacks structure risk state corruption and a use-after-free?
If multiple humidity sensors are probed, the last probed device overwrites
this global pointer. If that last device is later removed, the global pdev
pointer will point to freed memory.
When an event later arrives for the remaining active device,
humidity_proc_event() will dereference the freed pdev:
static int humidity_proc_event(struct hid_sensor_hub_device *hsdev,
u32 usage_id, void *pdev)
{
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
...
}
Should humidity_callbacks be dynamically allocated per-device or stored
within the device's private data rather than shared globally?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260806-28-apr-iio-redundant-argument-v5-temp-v5-0-f1f92c1d830f@gmail.com?part=6
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v5 07/13] iio: light: hid-sensor-prox: convert probe and teardown to devm-managed resources
2026-08-06 12:25 [PATCH v5 00/13] HID: iio: Introduce devm_ APIs for HID sensors Sanjay Chitroda via B4 Relay
` (5 preceding siblings ...)
2026-08-06 12:25 ` [PATCH v5 06/13] iio: humidity: hid-sensor-humidity: " Sanjay Chitroda via B4 Relay
@ 2026-08-06 12:25 ` Sanjay Chitroda via B4 Relay
2026-08-06 12:39 ` sashiko-bot
2026-08-06 12:25 ` [PATCH v5 08/13] iio: light: hid-sensor-als: " Sanjay Chitroda via B4 Relay
` (5 subsequent siblings)
12 siblings, 1 reply; 25+ messages in thread
From: Sanjay Chitroda via B4 Relay @ 2026-08-06 12:25 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Jiri Kosina, Srinivas Pandruvada, Benjamin Tissoires
Cc: linux-iio, linux-kernel, linux-input, Sanjay Chitroda
From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Convert HID IIO driver resource management to use devm-managed helpers,
tying the lifetime of all resources to the device.
HID trigger setup, IIO registration, and sensor hub callback resource
are now managed using devm APIs. Cleanup logic previously handled
explicitly in probe error and teardown paths.
This simplifies the probe path by removing goto-based error handling,
eliminates the remove callback entirely.
Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
drivers/iio/light/hid-sensor-prox.c | 40 ++++++++-----------------------------
1 file changed, 8 insertions(+), 32 deletions(-)
diff --git a/drivers/iio/light/hid-sensor-prox.c b/drivers/iio/light/hid-sensor-prox.c
index 5e28f9b7f40a..355b7b02868c 100644
--- a/drivers/iio/light/hid-sensor-prox.c
+++ b/drivers/iio/light/hid-sensor-prox.c
@@ -260,7 +260,8 @@ static int prox_parse_report(struct platform_device *pdev,
/* Function to initialize the processing for usage id */
static int hid_prox_probe(struct platform_device *pdev)
{
- struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
+ struct device *dev = &pdev->dev;
+ struct hid_sensor_hub_device *hsdev = dev_get_platdata(dev);
int ret = 0;
static const char *name = "prox";
struct iio_dev *indio_dev;
@@ -299,8 +300,8 @@ static int hid_prox_probe(struct platform_device *pdev)
atomic_set(&prox_state->common_attributes.data_ready, 0);
- ret = hid_sensor_setup_trigger(indio_dev, name,
- &prox_state->common_attributes);
+ ret = devm_hid_sensor_setup_trigger(dev, indio_dev, name,
+ &prox_state->common_attributes);
if (ret) {
dev_err(&pdev->dev, "trigger setup failed\n");
return ret;
@@ -309,38 +310,14 @@ static int hid_prox_probe(struct platform_device *pdev)
prox_state->callbacks.send_event = prox_proc_event;
prox_state->callbacks.capture_sample = prox_capture_sample;
prox_state->callbacks.pdev = pdev;
- ret = sensor_hub_register_callback(hsdev, hsdev->usage,
- &prox_state->callbacks);
+ ret = devm_sensor_hub_register_callback(dev, hsdev, hsdev->usage,
+ &prox_state->callbacks);
if (ret < 0) {
dev_err(&pdev->dev, "callback reg failed\n");
- goto error_remove_trigger;
- }
-
- ret = iio_device_register(indio_dev);
- if (ret) {
- dev_err(&pdev->dev, "device register failed\n");
- goto error_remove_callback;
+ return ret;
}
- return ret;
-
-error_remove_callback:
- sensor_hub_remove_callback(hsdev, hsdev->usage);
-error_remove_trigger:
- hid_sensor_remove_trigger(&prox_state->common_attributes);
- return ret;
-}
-
-/* Function to deinitialize the processing for usage id */
-static void hid_prox_remove(struct platform_device *pdev)
-{
- struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
- struct iio_dev *indio_dev = platform_get_drvdata(pdev);
- struct prox_state *prox_state = iio_priv(indio_dev);
-
- iio_device_unregister(indio_dev);
- sensor_hub_remove_callback(hsdev, hsdev->usage);
- hid_sensor_remove_trigger(&prox_state->common_attributes);
+ return devm_iio_device_register(dev, indio_dev);
}
static const struct platform_device_id hid_prox_ids[] = {
@@ -363,7 +340,6 @@ static struct platform_driver hid_prox_platform_driver = {
.pm = &hid_sensor_pm_ops,
},
.probe = hid_prox_probe,
- .remove = hid_prox_remove,
};
module_platform_driver(hid_prox_platform_driver);
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* Re: [PATCH v5 07/13] iio: light: hid-sensor-prox: convert probe and teardown to devm-managed resources
2026-08-06 12:25 ` [PATCH v5 07/13] iio: light: hid-sensor-prox: " Sanjay Chitroda via B4 Relay
@ 2026-08-06 12:39 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-08-06 12:39 UTC (permalink / raw)
To: Sanjay Chitroda; +Cc: linux-input, dmitry.torokhov
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Lack of synchronization between sensor hub callback removal and concurrent raw event execution leads to a potential use-after-free when the driver unbinds.
--
--- Patch [7]: [PATCH v5 07/13] iio: light: hid-sensor-prox: convert probe and teardown to devm-managed resources ---
commit 7c95d6a6926ff8d97206e6616bea5d2357682664
Author: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Subject: iio: light: hid-sensor-prox: convert probe and teardown to devm-managed resources
Convert HID IIO driver resource management to use devm-managed helpers,
tying the lifetime of all resources to the device. HID trigger setup, IIO
registration, and sensor hub callback resource are now managed using devm APIs.
This simplifies the probe path by removing goto-based error handling and
eliminates the remove callback entirely.
> diff --git a/drivers/iio/light/hid-sensor-prox.c b/drivers/iio/light/hid-sensor-prox.c
> index 5e28f9b7f40a1..355b7b02868ca 100644
> --- a/drivers/iio/light/hid-sensor-prox.c
> +++ b/drivers/iio/light/hid-sensor-prox.c
[ ... ]
> @@ -309,38 +310,14 @@ static int hid_prox_probe(struct platform_device *pdev)
> prox_state->callbacks.send_event = prox_proc_event;
> prox_state->callbacks.capture_sample = prox_capture_sample;
> prox_state->callbacks.pdev = pdev;
> - ret = sensor_hub_register_callback(hsdev, hsdev->usage,
> - &prox_state->callbacks);
> + ret = devm_sensor_hub_register_callback(dev, hsdev, hsdev->usage,
> + &prox_state->callbacks);
[Severity: High]
This is a pre-existing issue, but does removing the callback lack
synchronization with concurrent raw events, leading to a potential
use-after-free during driver unbind?
When the driver unbinds, sensor_hub_remove_callback() deletes the callback
under dyn_callback_lock but returns immediately without synchronizing against
ongoing events:
drivers/hid/hid-sensor-hub.c:sensor_hub_remove_callback() {
spin_lock_irqsave(&pdata->dyn_callback_lock, flags);
list_for_each_entry(callback, &pdata->dyn_callback_list, list)
if (callback->usage_id == usage_id &&
callback->hsdev == hsdev) {
list_del(&callback->list);
kfree(callback);
break;
}
spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
return 0;
}
Concurrently, if a hardware event triggers, sensor_hub_raw_event() can lookup
the callback and execute its functions while holding pdata->lock:
drivers/hid/hid-sensor-hub.c:sensor_hub_raw_event() {
...
callback = sensor_hub_get_callback(hdev,
report->field[i]->physical ? report->field[i]->physical :
report->field[i]->application,
report->field[i]->usage[0].collection_index,
&hsdev, &priv);
if (!callback) {
ptr += sz;
continue;
}
...
if (report->field[i]->logical)
callback->capture_sample(hsdev,
report->field[i]->logical, sz, ptr,
callback->pdev);
...
}
Because sensor_hub_remove_callback() doesn't wait for pdata->lock (or
otherwise synchronize with the raw event handler), the devres framework can
proceed to free prox_state while sensor_hub_raw_event() is still executing
and trying to call the now-freed capture_sample() or send_event() function
pointers.
> if (ret < 0) {
> dev_err(&pdev->dev, "callback reg failed\n");
> - goto error_remove_trigger;
> - }
> -
> - ret = iio_device_register(indio_dev);
> - if (ret) {
> - dev_err(&pdev->dev, "device register failed\n");
> - goto error_remove_callback;
> }
>
> - return ret;
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260806-28-apr-iio-redundant-argument-v5-temp-v5-0-f1f92c1d830f@gmail.com?part=7
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v5 08/13] iio: light: hid-sensor-als: convert probe and teardown to devm-managed resources
2026-08-06 12:25 [PATCH v5 00/13] HID: iio: Introduce devm_ APIs for HID sensors Sanjay Chitroda via B4 Relay
` (6 preceding siblings ...)
2026-08-06 12:25 ` [PATCH v5 07/13] iio: light: hid-sensor-prox: " Sanjay Chitroda via B4 Relay
@ 2026-08-06 12:25 ` Sanjay Chitroda via B4 Relay
2026-08-06 12:40 ` sashiko-bot
2026-08-06 12:25 ` [PATCH v5 09/13] iio: magnetometer: hid-sensor-magn-3d: " Sanjay Chitroda via B4 Relay
` (4 subsequent siblings)
12 siblings, 1 reply; 25+ messages in thread
From: Sanjay Chitroda via B4 Relay @ 2026-08-06 12:25 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Jiri Kosina, Srinivas Pandruvada, Benjamin Tissoires
Cc: linux-iio, linux-kernel, linux-input, Sanjay Chitroda
From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Convert HID IIO driver resource management to use devm-managed helpers,
tying the lifetime of all resources to the device.
HID trigger setup, IIO registration, and sensor hub callback resource
are now managed using devm APIs. Cleanup logic previously handled
explicitly in probe error and teardown paths.
This simplifies the probe path by removing goto-based error handling,
eliminates the remove callback entirely.
Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
drivers/iio/light/hid-sensor-als.c | 39 ++++++++------------------------------
1 file changed, 8 insertions(+), 31 deletions(-)
diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c
index 10bf46ea4f47..633fd1569987 100644
--- a/drivers/iio/light/hid-sensor-als.c
+++ b/drivers/iio/light/hid-sensor-als.c
@@ -348,7 +348,8 @@ static int als_parse_report(struct platform_device *pdev,
/* Function to initialize the processing for usage id */
static int hid_als_probe(struct platform_device *pdev)
{
- struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
+ struct device *dev = &pdev->dev;
+ struct hid_sensor_hub_device *hsdev = dev_get_platdata(dev);
int ret = 0;
static const char *name = "als";
struct iio_dev *indio_dev;
@@ -396,8 +397,8 @@ static int hid_als_probe(struct platform_device *pdev)
atomic_set(&als_state->common_attributes.data_ready, 0);
- ret = hid_sensor_setup_trigger(indio_dev, name,
- &als_state->common_attributes);
+ ret = devm_hid_sensor_setup_trigger(dev, indio_dev, name,
+ &als_state->common_attributes);
if (ret < 0) {
dev_err(&pdev->dev, "trigger setup failed\n");
return ret;
@@ -406,37 +407,14 @@ static int hid_als_probe(struct platform_device *pdev)
als_state->callbacks.send_event = als_proc_event;
als_state->callbacks.capture_sample = als_capture_sample;
als_state->callbacks.pdev = pdev;
- ret = sensor_hub_register_callback(hsdev, hsdev->usage, &als_state->callbacks);
+ ret = devm_sensor_hub_register_callback(dev, hsdev, hsdev->usage,
+ &als_state->callbacks);
if (ret < 0) {
dev_err(&pdev->dev, "callback reg failed\n");
- goto error_remove_trigger;
- }
-
- ret = iio_device_register(indio_dev);
- if (ret) {
- dev_err(&pdev->dev, "device register failed\n");
- goto error_remove_callback;
+ return ret;
}
- return ret;
-
-error_remove_callback:
- sensor_hub_remove_callback(hsdev, hsdev->usage);
-error_remove_trigger:
- hid_sensor_remove_trigger(&als_state->common_attributes);
- return ret;
-}
-
-/* Function to deinitialize the processing for usage id */
-static void hid_als_remove(struct platform_device *pdev)
-{
- struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
- struct iio_dev *indio_dev = platform_get_drvdata(pdev);
- struct als_state *als_state = iio_priv(indio_dev);
-
- iio_device_unregister(indio_dev);
- sensor_hub_remove_callback(hsdev, hsdev->usage);
- hid_sensor_remove_trigger(&als_state->common_attributes);
+ return devm_iio_device_register(dev, indio_dev);
}
static const struct platform_device_id hid_als_ids[] = {
@@ -459,7 +437,6 @@ static struct platform_driver hid_als_platform_driver = {
.pm = &hid_sensor_pm_ops,
},
.probe = hid_als_probe,
- .remove = hid_als_remove,
};
module_platform_driver(hid_als_platform_driver);
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* Re: [PATCH v5 08/13] iio: light: hid-sensor-als: convert probe and teardown to devm-managed resources
2026-08-06 12:25 ` [PATCH v5 08/13] iio: light: hid-sensor-als: " Sanjay Chitroda via B4 Relay
@ 2026-08-06 12:40 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-08-06 12:40 UTC (permalink / raw)
To: Sanjay Chitroda; +Cc: dmitry.torokhov, linux-input
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Definitive UAF Race Condition: Concurrent execution of sensor_hub_raw_event and driver teardown causes use-after-free on IIO state.
--
--- Patch [8]: [PATCH v5 08/13] iio: light: hid-sensor-als: convert probe and teardown to devm-managed resources ---
commit f3d5af6f98e23ba8f31c7ee56aed1d7b68b69703
Author: Sanjay Chitroda <sanjayembeddedse@gmail.com>
iio: light: hid-sensor-als: convert probe and teardown to devm-managed resources
Convert HID IIO driver resource management to use devm-managed helpers,
tying the lifetime of all resources to the device. This simplifies the probe
path by removing goto-based error handling and eliminates the remove callback
entirely.
> diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c
> index 10bf46ea4f475..633fd15699873 100644
> --- a/drivers/iio/light/hid-sensor-als.c
> +++ b/drivers/iio/light/hid-sensor-als.c
[ ... ]
> @@ -406,37 +407,14 @@ static int hid_als_probe(struct platform_device *pdev)
> als_state->callbacks.send_event = als_proc_event;
> als_state->callbacks.capture_sample = als_capture_sample;
> als_state->callbacks.pdev = pdev;
> - ret = sensor_hub_register_callback(hsdev, hsdev->usage, &als_state->callbacks);
> + ret = devm_sensor_hub_register_callback(dev, hsdev, hsdev->usage,
> + &als_state->callbacks);
[Severity: High]
This is a pre-existing issue, but does this code leave us vulnerable to a
use-after-free during driver unbind?
If a user unbinds the driver via sysfs while the HID sensor hub hardware is
actively sending events on another CPU, devres will trigger
sensor_hub_remove_callback().
The event thread sensor_hub_raw_event() processes HID events and calls
capture_sample() while holding the pdata->lock spinlock. However,
sensor_hub_remove_callback() only acquires dyn_callback_lock and fails to
acquire pdata->lock:
drivers/hid/hid-sensor-hub.c:sensor_hub_remove_callback() {
...
spin_lock_irqsave(&pdata->dyn_callback_lock, flags);
list_for_each_entry(callback, &pdata->dyn_callback_list, list)
if (callback->usage_id == usage_id && callback->hsdev == hsdev) {
list_del(&callback->list);
kfree(callback);
break;
}
spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
...
}
Because the unbind thread does not wait for actively executing event handlers
to finish, it can lead to this sequence:
CPU1 (Event thread)
sensor_hub_raw_event()
// holding pdata->lock
if (callback->capture_sample) {
// paused before or during capture_sample execution
CPU2 (Unbind)
devres cleanup calls sensor_hub_remove_callback()
list_del(&callback->list);
kfree(callback);
devres cleanup frees indio_dev (which contains als_state)
CPU1 (Event thread resumes)
callback->capture_sample(hsdev, ...) -> accesses freed als_state
Can we safely free als_state without ensuring that concurrently executing
event threads have fully completed?
> if (ret < 0) {
> dev_err(&pdev->dev, "callback reg failed\n");
> - goto error_remove_trigger;
> - }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260806-28-apr-iio-redundant-argument-v5-temp-v5-0-f1f92c1d830f@gmail.com?part=8
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v5 09/13] iio: magnetometer: hid-sensor-magn-3d: convert probe and teardown to devm-managed resources
2026-08-06 12:25 [PATCH v5 00/13] HID: iio: Introduce devm_ APIs for HID sensors Sanjay Chitroda via B4 Relay
` (7 preceding siblings ...)
2026-08-06 12:25 ` [PATCH v5 08/13] iio: light: hid-sensor-als: " Sanjay Chitroda via B4 Relay
@ 2026-08-06 12:25 ` Sanjay Chitroda via B4 Relay
2026-08-06 12:25 ` [PATCH v5 10/13] iio: orientation: hid-sensor-incl-3d: " Sanjay Chitroda via B4 Relay
` (3 subsequent siblings)
12 siblings, 0 replies; 25+ messages in thread
From: Sanjay Chitroda via B4 Relay @ 2026-08-06 12:25 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Jiri Kosina, Srinivas Pandruvada, Benjamin Tissoires
Cc: linux-iio, linux-kernel, linux-input, Sanjay Chitroda
From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Convert HID IIO driver resource management to use devm-managed helpers,
tying the lifetime of all resources to the device.
HID trigger setup, IIO registration, and sensor hub callback resource
are now managed using devm APIs. Cleanup logic previously handled
explicitly in probe error and teardown paths.
This simplifies the probe path by removing goto-based error handling,
eliminates the remove callback entirely.
Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
drivers/iio/magnetometer/hid-sensor-magn-3d.c | 41 ++++++---------------------
1 file changed, 9 insertions(+), 32 deletions(-)
diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index 5402cffa8326..c8b4fa7785c9 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -450,7 +450,8 @@ static int magn_3d_parse_report(struct platform_device *pdev,
/* Function to initialize the processing for usage id */
static int hid_magn_3d_probe(struct platform_device *pdev)
{
- struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
+ struct device *dev = &pdev->dev;
+ struct hid_sensor_hub_device *hsdev = dev_get_platdata(dev);
int ret = 0;
static char *name = "magn_3d";
struct iio_dev *indio_dev;
@@ -498,8 +499,8 @@ static int hid_magn_3d_probe(struct platform_device *pdev)
atomic_set(&magn_state->magn_flux_attributes.data_ready, 0);
- ret = hid_sensor_setup_trigger(indio_dev, name,
- &magn_state->magn_flux_attributes);
+ ret = devm_hid_sensor_setup_trigger(dev, indio_dev, name,
+ &magn_state->magn_flux_attributes);
if (ret < 0) {
dev_err(&pdev->dev, "trigger setup failed\n");
return ret;
@@ -508,38 +509,15 @@ static int hid_magn_3d_probe(struct platform_device *pdev)
magn_state->callbacks.send_event = magn_3d_proc_event;
magn_state->callbacks.capture_sample = magn_3d_capture_sample;
magn_state->callbacks.pdev = pdev;
- ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_COMPASS_3D,
- &magn_state->callbacks);
+ ret = devm_sensor_hub_register_callback(dev, hsdev,
+ HID_USAGE_SENSOR_COMPASS_3D,
+ &magn_state->callbacks);
if (ret < 0) {
dev_err(&pdev->dev, "callback reg failed\n");
- goto error_remove_trigger;
- }
-
- ret = iio_device_register(indio_dev);
- if (ret) {
- dev_err(&pdev->dev, "device register failed\n");
- goto error_remove_callback;
+ return ret;
}
- return ret;
-
-error_remove_callback:
- sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_COMPASS_3D);
-error_remove_trigger:
- hid_sensor_remove_trigger(&magn_state->magn_flux_attributes);
- return ret;
-}
-
-/* Function to deinitialize the processing for usage id */
-static void hid_magn_3d_remove(struct platform_device *pdev)
-{
- struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
- struct iio_dev *indio_dev = platform_get_drvdata(pdev);
- struct magn_3d_state *magn_state = iio_priv(indio_dev);
-
- iio_device_unregister(indio_dev);
- sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_COMPASS_3D);
- hid_sensor_remove_trigger(&magn_state->magn_flux_attributes);
+ return devm_iio_device_register(dev, indio_dev);
}
static const struct platform_device_id hid_magn_3d_ids[] = {
@@ -558,7 +536,6 @@ static struct platform_driver hid_magn_3d_platform_driver = {
.pm = &hid_sensor_pm_ops,
},
.probe = hid_magn_3d_probe,
- .remove = hid_magn_3d_remove,
};
module_platform_driver(hid_magn_3d_platform_driver);
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* [PATCH v5 10/13] iio: orientation: hid-sensor-incl-3d: convert probe and teardown to devm-managed resources
2026-08-06 12:25 [PATCH v5 00/13] HID: iio: Introduce devm_ APIs for HID sensors Sanjay Chitroda via B4 Relay
` (8 preceding siblings ...)
2026-08-06 12:25 ` [PATCH v5 09/13] iio: magnetometer: hid-sensor-magn-3d: " Sanjay Chitroda via B4 Relay
@ 2026-08-06 12:25 ` Sanjay Chitroda via B4 Relay
2026-08-06 12:25 ` [PATCH v5 11/13] iio: orientation: hid-sensor-rotation: " Sanjay Chitroda via B4 Relay
` (2 subsequent siblings)
12 siblings, 0 replies; 25+ messages in thread
From: Sanjay Chitroda via B4 Relay @ 2026-08-06 12:25 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Jiri Kosina, Srinivas Pandruvada, Benjamin Tissoires
Cc: linux-iio, linux-kernel, linux-input, Sanjay Chitroda
From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Convert HID IIO driver resource management to use devm-managed helpers,
tying the lifetime of all resources to the device.
HID trigger setup, IIO registration, and sensor hub callback resource
are now managed using devm APIs. Cleanup logic previously handled
explicitly in probe error and teardown paths.
This simplifies the probe path by removing goto-based error handling,
eliminates the remove callback entirely.
Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
drivers/iio/orientation/hid-sensor-incl-3d.c | 42 ++++++----------------------
1 file changed, 9 insertions(+), 33 deletions(-)
diff --git a/drivers/iio/orientation/hid-sensor-incl-3d.c b/drivers/iio/orientation/hid-sensor-incl-3d.c
index 435e70557721..b5f70732d035 100644
--- a/drivers/iio/orientation/hid-sensor-incl-3d.c
+++ b/drivers/iio/orientation/hid-sensor-incl-3d.c
@@ -293,7 +293,8 @@ static int incl_3d_parse_report(struct platform_device *pdev,
/* Function to initialize the processing for usage id */
static int hid_incl_3d_probe(struct platform_device *pdev)
{
- struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
+ struct device *dev = &pdev->dev;
+ struct hid_sensor_hub_device *hsdev = dev_get_platdata(dev);
int ret;
static char *name = "incli_3d";
struct iio_dev *indio_dev;
@@ -343,8 +344,8 @@ static int hid_incl_3d_probe(struct platform_device *pdev)
atomic_set(&incl_state->common_attributes.data_ready, 0);
- ret = hid_sensor_setup_trigger(indio_dev, name,
- &incl_state->common_attributes);
+ ret = devm_hid_sensor_setup_trigger(dev, indio_dev, name,
+ &incl_state->common_attributes);
if (ret) {
dev_err(&pdev->dev, "trigger setup failed\n");
return ret;
@@ -353,39 +354,15 @@ static int hid_incl_3d_probe(struct platform_device *pdev)
incl_state->callbacks.send_event = incl_3d_proc_event;
incl_state->callbacks.capture_sample = incl_3d_capture_sample;
incl_state->callbacks.pdev = pdev;
- ret = sensor_hub_register_callback(hsdev,
- HID_USAGE_SENSOR_INCLINOMETER_3D,
- &incl_state->callbacks);
+ ret = devm_sensor_hub_register_callback(dev, hsdev,
+ HID_USAGE_SENSOR_INCLINOMETER_3D,
+ &incl_state->callbacks);
if (ret) {
dev_err(&pdev->dev, "callback reg failed\n");
- goto error_remove_trigger;
- }
-
- ret = iio_device_register(indio_dev);
- if (ret) {
- dev_err(&pdev->dev, "device register failed\n");
- goto error_remove_callback;
+ return ret;
}
- return 0;
-
-error_remove_callback:
- sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_INCLINOMETER_3D);
-error_remove_trigger:
- hid_sensor_remove_trigger(&incl_state->common_attributes);
- return ret;
-}
-
-/* Function to deinitialize the processing for usage id */
-static void hid_incl_3d_remove(struct platform_device *pdev)
-{
- struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
- struct iio_dev *indio_dev = platform_get_drvdata(pdev);
- struct incl_3d_state *incl_state = iio_priv(indio_dev);
-
- iio_device_unregister(indio_dev);
- sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_INCLINOMETER_3D);
- hid_sensor_remove_trigger(&incl_state->common_attributes);
+ return devm_iio_device_register(dev, indio_dev);
}
static const struct platform_device_id hid_incl_3d_ids[] = {
@@ -404,7 +381,6 @@ static struct platform_driver hid_incl_3d_platform_driver = {
.pm = &hid_sensor_pm_ops,
},
.probe = hid_incl_3d_probe,
- .remove = hid_incl_3d_remove,
};
module_platform_driver(hid_incl_3d_platform_driver);
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* [PATCH v5 11/13] iio: orientation: hid-sensor-rotation: convert probe and teardown to devm-managed resources
2026-08-06 12:25 [PATCH v5 00/13] HID: iio: Introduce devm_ APIs for HID sensors Sanjay Chitroda via B4 Relay
` (9 preceding siblings ...)
2026-08-06 12:25 ` [PATCH v5 10/13] iio: orientation: hid-sensor-incl-3d: " Sanjay Chitroda via B4 Relay
@ 2026-08-06 12:25 ` Sanjay Chitroda via B4 Relay
2026-08-06 12:40 ` sashiko-bot
2026-08-06 12:25 ` [PATCH v5 12/13] iio: position: hid-sensor-custom-intel-hinge: " Sanjay Chitroda via B4 Relay
2026-08-06 12:25 ` [PATCH v5 13/13] iio: pressure: hid-sensor-press: " Sanjay Chitroda via B4 Relay
12 siblings, 1 reply; 25+ messages in thread
From: Sanjay Chitroda via B4 Relay @ 2026-08-06 12:25 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Jiri Kosina, Srinivas Pandruvada, Benjamin Tissoires
Cc: linux-iio, linux-kernel, linux-input, Sanjay Chitroda
From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Convert HID IIO driver resource management to use devm-managed helpers,
tying the lifetime of all resources to the device.
HID trigger setup, IIO registration, and sensor hub callback resource
are now managed using devm APIs. Cleanup logic previously handled
explicitly in probe error and teardown paths.
This simplifies the probe path by removing goto-based error handling,
eliminates the remove callback entirely.
Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
drivers/iio/orientation/hid-sensor-rotation.c | 40 ++++++---------------------
1 file changed, 8 insertions(+), 32 deletions(-)
diff --git a/drivers/iio/orientation/hid-sensor-rotation.c b/drivers/iio/orientation/hid-sensor-rotation.c
index 67ffa4f4075e..3ef89d66a88f 100644
--- a/drivers/iio/orientation/hid-sensor-rotation.c
+++ b/drivers/iio/orientation/hid-sensor-rotation.c
@@ -265,7 +265,8 @@ static int dev_rot_parse_report(struct platform_device *pdev,
/* Function to initialize the processing for usage id */
static int hid_dev_rot_probe(struct platform_device *pdev)
{
- struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
+ struct device *dev = &pdev->dev;
+ struct hid_sensor_hub_device *hsdev = dev_get_platdata(dev);
int ret;
char *name;
struct iio_dev *indio_dev;
@@ -320,8 +321,8 @@ static int hid_dev_rot_probe(struct platform_device *pdev)
atomic_set(&rot_state->common_attributes.data_ready, 0);
- ret = hid_sensor_setup_trigger(indio_dev, name,
- &rot_state->common_attributes);
+ ret = devm_hid_sensor_setup_trigger(dev, indio_dev, name,
+ &rot_state->common_attributes);
if (ret) {
dev_err(&pdev->dev, "trigger setup failed\n");
return ret;
@@ -330,38 +331,14 @@ static int hid_dev_rot_probe(struct platform_device *pdev)
rot_state->callbacks.send_event = dev_rot_proc_event;
rot_state->callbacks.capture_sample = dev_rot_capture_sample;
rot_state->callbacks.pdev = pdev;
- ret = sensor_hub_register_callback(hsdev, hsdev->usage,
- &rot_state->callbacks);
+ ret = devm_sensor_hub_register_callback(dev, hsdev, hsdev->usage,
+ &rot_state->callbacks);
if (ret) {
dev_err(&pdev->dev, "callback reg failed\n");
- goto error_remove_trigger;
- }
-
- ret = iio_device_register(indio_dev);
- if (ret) {
- dev_err(&pdev->dev, "device register failed\n");
- goto error_remove_callback;
+ return ret;
}
- return 0;
-
-error_remove_callback:
- sensor_hub_remove_callback(hsdev, hsdev->usage);
-error_remove_trigger:
- hid_sensor_remove_trigger(&rot_state->common_attributes);
- return ret;
-}
-
-/* Function to deinitialize the processing for usage id */
-static void hid_dev_rot_remove(struct platform_device *pdev)
-{
- struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
- struct iio_dev *indio_dev = platform_get_drvdata(pdev);
- struct dev_rot_state *rot_state = iio_priv(indio_dev);
-
- iio_device_unregister(indio_dev);
- sensor_hub_remove_callback(hsdev, hsdev->usage);
- hid_sensor_remove_trigger(&rot_state->common_attributes);
+ return devm_iio_device_register(dev, indio_dev);
}
static const struct platform_device_id hid_dev_rot_ids[] = {
@@ -388,7 +365,6 @@ static struct platform_driver hid_dev_rot_platform_driver = {
.pm = &hid_sensor_pm_ops,
},
.probe = hid_dev_rot_probe,
- .remove = hid_dev_rot_remove,
};
module_platform_driver(hid_dev_rot_platform_driver);
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* Re: [PATCH v5 11/13] iio: orientation: hid-sensor-rotation: convert probe and teardown to devm-managed resources
2026-08-06 12:25 ` [PATCH v5 11/13] iio: orientation: hid-sensor-rotation: " Sanjay Chitroda via B4 Relay
@ 2026-08-06 12:40 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-08-06 12:40 UTC (permalink / raw)
To: Sanjay Chitroda; +Cc: dmitry.torokhov, linux-input
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Race condition between sensor_hub_raw_event() and driver unbind leads to Use-After-Free.
--
--- Patch [11]: [PATCH v5 11/13] iio: orientation: hid-sensor-rotation: convert probe and teardown to devm-managed resources ---
commit 3160b0601a08ac2a6833abd2c964d88a54dc98cc
Author: Sanjay Chitroda <sanjayembeddedse@gmail.com>
iio: orientation: hid-sensor-rotation: convert probe and teardown to devm-managed resources
This patch converts the HID IIO driver resource management to use
devm-managed helpers. It transitions HID trigger setup, IIO registration,
and sensor hub callback resources to devm APIs, simplifying probe error
handling and removing the remove callback.
> diff --git a/drivers/iio/orientation/hid-sensor-rotation.c b/drivers/iio/orientation/hid-sensor-rotation.c
> index 67ffa4f4075e3..3ef89d66a88f9 100644
> --- a/drivers/iio/orientation/hid-sensor-rotation.c
> +++ b/drivers/iio/orientation/hid-sensor-rotation.c
[ ... ]
> @@ -330,38 +331,14 @@ static int hid_dev_rot_probe(struct platform_device *pdev)
> rot_state->callbacks.send_event = dev_rot_proc_event;
> rot_state->callbacks.capture_sample = dev_rot_capture_sample;
> rot_state->callbacks.pdev = pdev;
> - ret = sensor_hub_register_callback(hsdev, hsdev->usage,
> - &rot_state->callbacks);
> + ret = devm_sensor_hub_register_callback(dev, hsdev, hsdev->usage,
> + &rot_state->callbacks);
[Severity: High]
This isn't a bug introduced by this patch, but does removing the callback
registration here leave us vulnerable to a use-after-free during unbind?
When a user unbinds the driver or an error occurs during probe, devres begins
cleanup and calls sensor_hub_remove_callback().
However, this function does not appear to synchronize with concurrent readers:
drivers/hid/hid-sensor-hub.c:sensor_hub_remove_callback() {
...
spin_lock_irqsave(&pdata->dyn_callback_lock, flags);
...
spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
return 0;
}
Because it doesn't take pdata->lock to wait for executing callbacks, a
concurrent HID event running in sensor_hub_raw_event() can hold a pointer to
the callback.
Devres will then proceed to free the IIO device memory (indio_dev and
rot_state).
If the concurrent event then executes callback->capture_sample(), could it
access the freed memory?
drivers/iio/orientation/hid-sensor-rotation.c:dev_rot_capture_sample() {
struct iio_dev *indio_dev = platform_get_drvdata(priv);
struct dev_rot_state *rot_state = iio_priv(indio_dev);
...
}
> if (ret) {
> dev_err(&pdev->dev, "callback reg failed\n");
> - goto error_remove_trigger;
> - }
> -
> - ret = iio_device_register(indio_dev);
> - if (ret) {
> - dev_err(&pdev->dev, "device register failed\n");
> - goto error_remove_callback;
> + return ret;
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260806-28-apr-iio-redundant-argument-v5-temp-v5-0-f1f92c1d830f@gmail.com?part=11
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v5 12/13] iio: position: hid-sensor-custom-intel-hinge: convert probe and teardown to devm-managed resources
2026-08-06 12:25 [PATCH v5 00/13] HID: iio: Introduce devm_ APIs for HID sensors Sanjay Chitroda via B4 Relay
` (10 preceding siblings ...)
2026-08-06 12:25 ` [PATCH v5 11/13] iio: orientation: hid-sensor-rotation: " Sanjay Chitroda via B4 Relay
@ 2026-08-06 12:25 ` Sanjay Chitroda via B4 Relay
2026-08-06 12:48 ` sashiko-bot
2026-08-06 12:25 ` [PATCH v5 13/13] iio: pressure: hid-sensor-press: " Sanjay Chitroda via B4 Relay
12 siblings, 1 reply; 25+ messages in thread
From: Sanjay Chitroda via B4 Relay @ 2026-08-06 12:25 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Jiri Kosina, Srinivas Pandruvada, Benjamin Tissoires
Cc: linux-iio, linux-kernel, linux-input, Sanjay Chitroda
From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Convert HID IIO driver resource management to use devm-managed helpers,
tying the lifetime of all resources to the device.
HID trigger setup, IIO registration, and sensor hub callback resource
are now managed using devm APIs. Cleanup logic previously handled
explicitly in probe error and teardown paths.
This simplifies the probe path by removing goto-based error handling,
eliminates the remove callback entirely.
Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
.../iio/position/hid-sensor-custom-intel-hinge.c | 38 ++++------------------
1 file changed, 7 insertions(+), 31 deletions(-)
diff --git a/drivers/iio/position/hid-sensor-custom-intel-hinge.c b/drivers/iio/position/hid-sensor-custom-intel-hinge.c
index 7f6186fea004..101d84b533c9 100644
--- a/drivers/iio/position/hid-sensor-custom-intel-hinge.c
+++ b/drivers/iio/position/hid-sensor-custom-intel-hinge.c
@@ -263,7 +263,8 @@ static int hinge_parse_report(struct platform_device *pdev,
/* Function to initialize the processing for usage id */
static int hid_hinge_probe(struct platform_device *pdev)
{
- struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
+ struct device *dev = &pdev->dev;
+ struct hid_sensor_hub_device *hsdev = dev_get_platdata(dev);
struct hinge_state *st;
struct iio_dev *indio_dev;
int ret;
@@ -310,8 +311,8 @@ static int hid_hinge_probe(struct platform_device *pdev)
indio_dev->modes = INDIO_DIRECT_MODE;
atomic_set(&st->common_attributes.data_ready, 0);
- ret = hid_sensor_setup_trigger(indio_dev, indio_dev->name,
- &st->common_attributes);
+ ret = devm_hid_sensor_setup_trigger(dev, indio_dev, indio_dev->name,
+ &st->common_attributes);
if (ret < 0) {
dev_err(&pdev->dev, "trigger setup failed\n");
return ret;
@@ -320,37 +321,13 @@ static int hid_hinge_probe(struct platform_device *pdev)
st->callbacks.send_event = hinge_proc_event;
st->callbacks.capture_sample = hinge_capture_sample;
st->callbacks.pdev = pdev;
- ret = sensor_hub_register_callback(hsdev, hsdev->usage, &st->callbacks);
+ ret = devm_sensor_hub_register_callback(dev, hsdev, hsdev->usage, &st->callbacks);
if (ret < 0) {
dev_err(&pdev->dev, "callback reg failed\n");
- goto error_remove_trigger;
- }
-
- ret = iio_device_register(indio_dev);
- if (ret) {
- dev_err(&pdev->dev, "device register failed\n");
- goto error_remove_callback;
+ return ret;
}
- return ret;
-
-error_remove_callback:
- sensor_hub_remove_callback(hsdev, hsdev->usage);
-error_remove_trigger:
- hid_sensor_remove_trigger(&st->common_attributes);
- return ret;
-}
-
-/* Function to deinitialize the processing for usage id */
-static void hid_hinge_remove(struct platform_device *pdev)
-{
- struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
- struct iio_dev *indio_dev = platform_get_drvdata(pdev);
- struct hinge_state *st = iio_priv(indio_dev);
-
- iio_device_unregister(indio_dev);
- sensor_hub_remove_callback(hsdev, hsdev->usage);
- hid_sensor_remove_trigger(&st->common_attributes);
+ return devm_iio_device_register(dev, indio_dev);
}
static const struct platform_device_id hid_hinge_ids[] = {
@@ -369,7 +346,6 @@ static struct platform_driver hid_hinge_platform_driver = {
.pm = &hid_sensor_pm_ops,
},
.probe = hid_hinge_probe,
- .remove = hid_hinge_remove,
};
module_platform_driver(hid_hinge_platform_driver);
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* Re: [PATCH v5 12/13] iio: position: hid-sensor-custom-intel-hinge: convert probe and teardown to devm-managed resources
2026-08-06 12:25 ` [PATCH v5 12/13] iio: position: hid-sensor-custom-intel-hinge: " Sanjay Chitroda via B4 Relay
@ 2026-08-06 12:48 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-08-06 12:48 UTC (permalink / raw)
To: Sanjay Chitroda; +Cc: linux-input, dmitry.torokhov
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] This problem wasn't introduced by this patch, but there is a possible Use-After-Free (UAF) during driver unbind or probe error due to missing synchronization with concurrent hardware events.
--
--- Patch [12]: [PATCH v5 12/13] iio: position: hid-sensor-custom-intel-hinge: convert probe and teardown to devm-managed resources ---
commit 9db33d404c2c76bf6835ddae77ee4ee1c86c8f21
Author: Sanjay Chitroda <sanjayembeddedse@gmail.com>
iio: position: hid-sensor-custom-intel-hinge: convert probe and teardown to devm-managed resources
This patch converts the HID IIO driver resource management to use
devm-managed helpers, tying the lifetime of resources to the device.
It simplifies the probe path by removing explicit error handling and
eliminates the remove callback.
> diff --git a/drivers/iio/position/hid-sensor-custom-intel-hinge.c b/drivers/iio/position/hid-sensor-custom-intel-hinge.c
> index 7f6186fea0047..101d84b533c9e 100644
> --- a/drivers/iio/position/hid-sensor-custom-intel-hinge.c
> +++ b/drivers/iio/position/hid-sensor-custom-intel-hinge.c
[ ... ]
> @@ -320,37 +321,13 @@ static int hid_hinge_probe(struct platform_device *pdev)
> st->callbacks.send_event = hinge_proc_event;
> st->callbacks.capture_sample = hinge_capture_sample;
> st->callbacks.pdev = pdev;
> - ret = sensor_hub_register_callback(hsdev, hsdev->usage, &st->callbacks);
> + ret = devm_sensor_hub_register_callback(dev, hsdev, hsdev->usage, &st->callbacks);
[Severity: High]
This is a pre-existing issue, but can this sequence lead to a write-after-free
if a hardware event races with driver unbind or probe error?
During devm cleanup, sensor_hub_remove_callback() removes the callback from
the list without waiting for concurrent readers. The cleanup then immediately
frees the hinge_state structure allocated earlier.
If a concurrent HID hardware event triggers sensor_hub_raw_event(), can it
fetch the callback and execute hinge_capture_sample() after the structure
has been freed:
drivers/iio/position/hid-sensor-custom-intel-hinge.c:hinge_capture_sample() {
...
st->scan.hinge_val[offset] = *(u32 *)raw_data;
...
}
Should there be synchronization to ensure concurrent hardware events have
completed before the memory backing the callback is freed?
> if (ret < 0) {
> dev_err(&pdev->dev, "callback reg failed\n");
> - goto error_remove_trigger;
> - }
> -
> - ret = iio_device_register(indio_dev);
> - if (ret) {
> - dev_err(&pdev->dev, "device register failed\n");
> - goto error_remove_callback;
> + return ret;
> }
>
> - return ret;
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260806-28-apr-iio-redundant-argument-v5-temp-v5-0-f1f92c1d830f@gmail.com?part=12
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v5 13/13] iio: pressure: hid-sensor-press: convert probe and teardown to devm-managed resources
2026-08-06 12:25 [PATCH v5 00/13] HID: iio: Introduce devm_ APIs for HID sensors Sanjay Chitroda via B4 Relay
` (11 preceding siblings ...)
2026-08-06 12:25 ` [PATCH v5 12/13] iio: position: hid-sensor-custom-intel-hinge: " Sanjay Chitroda via B4 Relay
@ 2026-08-06 12:25 ` Sanjay Chitroda via B4 Relay
2026-08-06 12:44 ` sashiko-bot
12 siblings, 1 reply; 25+ messages in thread
From: Sanjay Chitroda via B4 Relay @ 2026-08-06 12:25 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Jiri Kosina, Srinivas Pandruvada, Benjamin Tissoires
Cc: linux-iio, linux-kernel, linux-input, Sanjay Chitroda
From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Convert HID IIO driver resource management to use devm-managed helpers,
tying the lifetime of all resources to the device.
HID trigger setup, IIO registration, and sensor hub callback resource
are now managed using devm APIs. Cleanup logic previously handled
explicitly in probe error and teardown paths.
This simplifies the probe path by removing goto-based error handling,
eliminates the remove callback entirely.
Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
drivers/iio/pressure/hid-sensor-press.c | 41 ++++++++-------------------------
1 file changed, 9 insertions(+), 32 deletions(-)
diff --git a/drivers/iio/pressure/hid-sensor-press.c b/drivers/iio/pressure/hid-sensor-press.c
index 4e0f42fefd6b..8ebb8f54a0cb 100644
--- a/drivers/iio/pressure/hid-sensor-press.c
+++ b/drivers/iio/pressure/hid-sensor-press.c
@@ -230,7 +230,8 @@ static int press_parse_report(struct platform_device *pdev,
/* Function to initialize the processing for usage id */
static int hid_press_probe(struct platform_device *pdev)
{
- struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
+ struct device *dev = &pdev->dev;
+ struct hid_sensor_hub_device *hsdev = dev_get_platdata(dev);
int ret = 0;
static const char *name = "press";
struct iio_dev *indio_dev;
@@ -278,8 +279,8 @@ static int hid_press_probe(struct platform_device *pdev)
atomic_set(&press_state->common_attributes.data_ready, 0);
- ret = hid_sensor_setup_trigger(indio_dev, name,
- &press_state->common_attributes);
+ ret = devm_hid_sensor_setup_trigger(dev, indio_dev, name,
+ &press_state->common_attributes);
if (ret) {
dev_err(&pdev->dev, "trigger setup failed\n");
return ret;
@@ -288,38 +289,15 @@ static int hid_press_probe(struct platform_device *pdev)
press_state->callbacks.send_event = press_proc_event;
press_state->callbacks.capture_sample = press_capture_sample;
press_state->callbacks.pdev = pdev;
- ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_PRESSURE,
- &press_state->callbacks);
+ ret = devm_sensor_hub_register_callback(dev, hsdev,
+ HID_USAGE_SENSOR_PRESSURE,
+ &press_state->callbacks);
if (ret < 0) {
dev_err(&pdev->dev, "callback reg failed\n");
- goto error_remove_trigger;
- }
-
- ret = iio_device_register(indio_dev);
- if (ret) {
- dev_err(&pdev->dev, "device register failed\n");
- goto error_remove_callback;
+ return ret;
}
- return ret;
-
-error_remove_callback:
- sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_PRESSURE);
-error_remove_trigger:
- hid_sensor_remove_trigger(&press_state->common_attributes);
- return ret;
-}
-
-/* Function to deinitialize the processing for usage id */
-static void hid_press_remove(struct platform_device *pdev)
-{
- struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
- struct iio_dev *indio_dev = platform_get_drvdata(pdev);
- struct press_state *press_state = iio_priv(indio_dev);
-
- iio_device_unregister(indio_dev);
- sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_PRESSURE);
- hid_sensor_remove_trigger(&press_state->common_attributes);
+ return devm_iio_device_register(dev, indio_dev);
}
static const struct platform_device_id hid_press_ids[] = {
@@ -338,7 +316,6 @@ static struct platform_driver hid_press_platform_driver = {
.pm = &hid_sensor_pm_ops,
},
.probe = hid_press_probe,
- .remove = hid_press_remove,
};
module_platform_driver(hid_press_platform_driver);
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread* Re: [PATCH v5 13/13] iio: pressure: hid-sensor-press: convert probe and teardown to devm-managed resources
2026-08-06 12:25 ` [PATCH v5 13/13] iio: pressure: hid-sensor-press: " Sanjay Chitroda via B4 Relay
@ 2026-08-06 12:44 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-08-06 12:44 UTC (permalink / raw)
To: Sanjay Chitroda; +Cc: linux-input, dmitry.torokhov
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Concurrency UAF during device unbind between `sensor_hub_raw_event` and `sensor_hub_remove_callback`.
--
--- Patch [13]: [PATCH v5 13/13] iio: pressure: hid-sensor-press: convert probe and teardown to devm-managed resources ---
commit 45fb35e2b8f4da70b5748e13b1091b8fdbd11a47
Author: Sanjay Chitroda <sanjayembeddedse@gmail.com>
iio: pressure: hid-sensor-press: convert probe and teardown to devm-managed resources
The commit converts HID IIO driver resource management to devm-managed helpers.
This ties the lifetime of all resources to the device and simplifies the probe
path by removing explicit error handling and teardown paths.
> diff --git a/drivers/iio/pressure/hid-sensor-press.c b/drivers/iio/pressure/hid-sensor-press.c
> index 4e0f42fefd6b4..8ebb8f54a0cb9 100644
> --- a/drivers/iio/pressure/hid-sensor-press.c
> +++ b/drivers/iio/pressure/hid-sensor-press.c
[ ... ]
> @@ -288,38 +289,15 @@ static int hid_press_probe(struct platform_device *pdev)
> press_state->callbacks.send_event = press_proc_event;
> press_state->callbacks.capture_sample = press_capture_sample;
> press_state->callbacks.pdev = pdev;
> - ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_PRESSURE,
> - &press_state->callbacks);
> + ret = devm_sensor_hub_register_callback(dev, hsdev,
> + HID_USAGE_SENSOR_PRESSURE,
> + &press_state->callbacks);
[Severity: High]
This is a pre-existing issue, but can unbinding this driver race with event
delivery and cause a use-after-free?
When the child driver unbinds, devm triggers sensor_hub_remove_callback(),
which removes the callback from dyn_callback_list and frees it using
dyn_callback_lock:
drivers/hid/hid-sensor-hub.c:sensor_hub_remove_callback() {
...
spin_lock_irqsave(&pdata->dyn_callback_lock, flags);
list_for_each_entry(callback, &pdata->dyn_callback_list, list)
if (callback->usage_id == usage_id &&
callback->hsdev == hsdev) {
list_del(&callback->list);
kfree(callback);
break;
}
spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
...
}
After this, devm frees the IIO device's private data (press_state).
However, there doesn't appear to be any synchronization to ensure that a
concurrently executing sensor_hub_raw_event() on another CPU has finished
using the callback pointer.
If sensor_hub_raw_event() is actively dispatching an event under pdata->lock,
could it invoke the callback with a stale pointer and write to freed memory?
drivers/hid/hid-sensor-hub.c:sensor_hub_raw_event() {
...
callback = sensor_hub_get_callback(hdev,
report->field[i]->physical ? report->field[i]->physical :
report->field[i]->application,
report->field[i]->usage[0].collection_index,
&hsdev, &priv);
if (!callback) {
ptr += sz;
continue;
}
...
if (callback->capture_sample) {
if (report->field[i]->logical)
callback->capture_sample(hsdev,
report->field[i]->logical, sz, ptr,
callback->pdev);
else
callback->capture_sample(hsdev,
report->field[i]->usage->hid, sz, ptr,
callback->pdev);
}
...
}
> if (ret < 0) {
> dev_err(&pdev->dev, "callback reg failed\n");
> - goto error_remove_trigger;
> - }
> -
> - ret = iio_device_register(indio_dev);
> - if (ret) {
> - dev_err(&pdev->dev, "device register failed\n");
> - goto error_remove_callback;
> }
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260806-28-apr-iio-redundant-argument-v5-temp-v5-0-f1f92c1d830f@gmail.com?part=13
^ permalink raw reply [flat|nested] 25+ messages in thread