Linux Input/HID development
 help / color / mirror / Atom feed
* [PATCH v1] iio: temperature: hid-sensor-temperature: switch to non-devm iio_device_register()
From: Sanjay Chitroda @ 2026-06-22  5:21 UTC (permalink / raw)
  To: jikos, jic23, srinivas.pandruvada
  Cc: dlechner, nuno.sa, andy, hongyan.song, linux-input, linux-iio,
	linux-kernel

From: Sanjay Chitroda <sanjayembeddedse@gmail.com>

Avoid using devm_iio_device_register(), as this driver requires explicit
error handling and teardown ordering.

Mixing devm_* APIs with goto-based error unwinding breaks the expected
LIFO resource release model and can introduce race windows during device
removal. In particular, the IIO device may remain visible to userspace
while dependent resources are already being freed, potentially leading
to use-after-free issues.

Add explicit iio_device_unregister() call in the teardown path to ensure
deterministic cleanup and follow kernel resource management conventions.

Fixes: 59d0f2da3569 ("iio: hid: Add temperature sensor support")
Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
 drivers/iio/temperature/hid-sensor-temperature.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/temperature/hid-sensor-temperature.c b/drivers/iio/temperature/hid-sensor-temperature.c
index 9f628a8e5cfb..34bff7e9f3a3 100644
--- a/drivers/iio/temperature/hid-sensor-temperature.c
+++ b/drivers/iio/temperature/hid-sensor-temperature.c
@@ -244,7 +244,7 @@ static int hid_temperature_probe(struct platform_device *pdev)
 	if (ret)
 		goto error_remove_trigger;
 
-	ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev);
+	ret = iio_device_register(indio_dev);
 	if (ret)
 		goto error_remove_callback;
 
@@ -264,6 +264,7 @@ static void hid_temperature_remove(struct platform_device *pdev)
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 	struct temperature_state *temp_st = iio_priv(indio_dev);
 
+	iio_device_unregister(indio_dev);
 	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TEMPERATURE);
 	hid_sensor_remove_trigger(indio_dev, &temp_st->common_attributes);
 }
-- 
--


^ permalink raw reply related

* [PATCH v2 0/8] HID: iio: Avoid race between callback setup and device exposure
From: Sanjay Chitroda @ 2026-06-22  5:29 UTC (permalink / raw)
  To: Jiri Kosina, Jonathan Cameron, Srinivas Pandruvada, David Lechner,
	Nuno Sá, Andy Shevchenko, Archana Patni, Song Hongyan
  Cc: linux-input, linux-iio, linux-kernel, srinivas pandruvada,
	Sanjay Chitroda

Hi all,

This series avoid a race condition in HID IIO drivers related to the
ordering between callback registration and device exposure.

Currently, several HID IIO drivers register the IIO device (making it
visible to userspace and other kernel consumers) before all required
callbacks and resources are fully initialized, or rely on devm-based
cleanup in a way that does not guarantee correct teardown ordering.
This creates a window where the device can be accessed while it is
not fully initialized or is being torn down, potentially leading to
sample drop or stale/no data.

To handle this, the series ensures that:
  - All required callbacks and resources are set up before the device
    is registered with the IIO core
  - Resource cleanup is performed explicitly where ordering matters

PS: This is prepratory series to convert all HID IIO driver to devm.

Testing:
  - Compiled with W=1 for each patch in series

---
Changes in v2:
- Drop fixes tag and rectify commit message with reference to that
- Link to v1: https://patch.msgid.link/20260606-5-june-hid-iio-race-fixes-v1-0-27a848c5758f@gmail.com

To: Jiri Kosina <jikos@kernel.org>
To: Jonathan Cameron <jic23@kernel.org>
To: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
To: David Lechner <dlechner@baylibre.com>
To: Nuno Sá <nuno.sa@analog.com>
To: Andy Shevchenko <andy@kernel.org>
Cc: linux-input@vger.kernel.org
Cc: linux-iio@vger.kernel.org
Cc: linux-kernel@vger.kernel.org

---
Sanjay Chitroda (8):
      iio: orientation: hid-sensor-rotation: Avoid race between callback setup and device exposure
      iio: orientation: hid-sensor-incl-3d: Avoid race between callback setup and device exposure
      iio: gyro: hid-sensor-gyro-3d: Avoid race between callback setup and device exposure
      iio: pressure: hid-sensor-press: Avoid race between callback setup and device exposure
      iio: light: hid-sensor-prox: Avoid race between callback setup and device exposure
      iio: light: hid-sensor-als: Avoid race between callback setup and device exposure
      iio: magnetometer: hid-sensor-magn-3d: Avoid race between callback setup and device exposure
      iio: accel: hid-sensor-accel-3d: Avoid race between callback setup and device exposure

 drivers/iio/accel/hid-sensor-accel-3d.c       | 20 ++++++++++----------
 drivers/iio/gyro/hid-sensor-gyro-3d.c         | 20 ++++++++++----------
 drivers/iio/light/hid-sensor-als.c            | 20 ++++++++++----------
 drivers/iio/light/hid-sensor-prox.c           | 20 ++++++++++----------
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 20 ++++++++++----------
 drivers/iio/orientation/hid-sensor-incl-3d.c  | 20 ++++++++++----------
 drivers/iio/orientation/hid-sensor-rotation.c | 20 ++++++++++----------
 drivers/iio/pressure/hid-sensor-press.c       | 20 ++++++++++----------
 8 files changed, 80 insertions(+), 80 deletions(-)
---
base-commit: cc746297b23e89bd5df9f91f3a0ca209e8991763
change-id: 20260605-5-june-hid-iio-race-fixes-f8b981f82b80

Best regards,
--  
Sanjay Chitroda <sanjayembeddedse@gmail.com>


^ permalink raw reply

* [PATCH v2 1/8] iio: orientation: hid-sensor-rotation: Avoid race between callback setup and device exposure
From: Sanjay Chitroda @ 2026-06-22  5:29 UTC (permalink / raw)
  To: Jiri Kosina, Jonathan Cameron, Srinivas Pandruvada, David Lechner,
	Nuno Sá, Andy Shevchenko, Archana Patni, Song Hongyan
  Cc: linux-input, linux-iio, linux-kernel, srinivas pandruvada,
	Sanjay Chitroda
In-Reply-To: <20260622-5-june-hid-iio-race-fixes-v2-0-1cfabcd1881e@gmail.com>

From: Sanjay Chitroda <sanjayembeddedse@gmail.com>

The driver currently exposes the IIO device to userspace before
completing sensor hub callback registration, and similarly removes
callbacks while the device can still be accessed during teardown.

This creates a timing window where userspace may enable the buffer
before callbacks are available. In such cases:
- samples can be dropped,
- buffered reads may observe stale or no data.

Reorder probe and remove paths to ensure callbacks are active before
device exposure and are removed after device is no longer accessible.

This avoids a race window leading to data loss.

Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
 drivers/iio/orientation/hid-sensor-rotation.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/iio/orientation/hid-sensor-rotation.c b/drivers/iio/orientation/hid-sensor-rotation.c
index 20563d8efaf6..6773bb0ec204 100644
--- a/drivers/iio/orientation/hid-sensor-rotation.c
+++ b/drivers/iio/orientation/hid-sensor-rotation.c
@@ -332,12 +332,6 @@ static int hid_dev_rot_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = iio_device_register(indio_dev);
-	if (ret) {
-		dev_err(&pdev->dev, "device register failed\n");
-		goto error_remove_trigger;
-	}
-
 	rot_state->callbacks.send_event = dev_rot_proc_event;
 	rot_state->callbacks.capture_sample = dev_rot_capture_sample;
 	rot_state->callbacks.pdev = pdev;
@@ -345,13 +339,19 @@ static int hid_dev_rot_probe(struct platform_device *pdev)
 					&rot_state->callbacks);
 	if (ret) {
 		dev_err(&pdev->dev, "callback reg failed\n");
-		goto error_iio_unreg;
+		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 0;
 
-error_iio_unreg:
-	iio_device_unregister(indio_dev);
+error_remove_callback:
+	sensor_hub_remove_callback(hsdev, hsdev->usage);
 error_remove_trigger:
 	hid_sensor_remove_trigger(indio_dev, &rot_state->common_attributes);
 	return ret;
@@ -364,8 +364,8 @@ static void hid_dev_rot_remove(struct platform_device *pdev)
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 	struct dev_rot_state *rot_state = iio_priv(indio_dev);
 
-	sensor_hub_remove_callback(hsdev, hsdev->usage);
 	iio_device_unregister(indio_dev);
+	sensor_hub_remove_callback(hsdev, hsdev->usage);
 	hid_sensor_remove_trigger(indio_dev, &rot_state->common_attributes);
 }
 

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 2/8] iio: orientation: hid-sensor-incl-3d: Avoid race between callback setup and device exposure
From: Sanjay Chitroda @ 2026-06-22  5:29 UTC (permalink / raw)
  To: Jiri Kosina, Jonathan Cameron, Srinivas Pandruvada, David Lechner,
	Nuno Sá, Andy Shevchenko, Archana Patni, Song Hongyan
  Cc: linux-input, linux-iio, linux-kernel, srinivas pandruvada,
	Sanjay Chitroda
In-Reply-To: <20260622-5-june-hid-iio-race-fixes-v2-0-1cfabcd1881e@gmail.com>

From: Sanjay Chitroda <sanjayembeddedse@gmail.com>

The driver currently exposes the IIO device to userspace before
completing sensor hub callback registration, and similarly removes
callbacks while the device can still be accessed during teardown.

This creates a timing window where userspace may enable the buffer
before callbacks are available. In such cases:
- samples can be dropped,
- buffered reads may observe stale or no data.

Reorder probe and remove paths to ensure callbacks are active before
device exposure and are removed after device is no longer accessible.

This avoids a race window leading to data loss.

Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
 drivers/iio/orientation/hid-sensor-incl-3d.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/iio/orientation/hid-sensor-incl-3d.c b/drivers/iio/orientation/hid-sensor-incl-3d.c
index c7fbff498be7..5696e4ef3633 100644
--- a/drivers/iio/orientation/hid-sensor-incl-3d.c
+++ b/drivers/iio/orientation/hid-sensor-incl-3d.c
@@ -356,12 +356,6 @@ static int hid_incl_3d_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = iio_device_register(indio_dev);
-	if (ret) {
-		dev_err(&pdev->dev, "device register failed\n");
-		goto error_remove_trigger;
-	}
-
 	incl_state->callbacks.send_event = incl_3d_proc_event;
 	incl_state->callbacks.capture_sample = incl_3d_capture_sample;
 	incl_state->callbacks.pdev = pdev;
@@ -370,13 +364,19 @@ static int hid_incl_3d_probe(struct platform_device *pdev)
 					&incl_state->callbacks);
 	if (ret) {
 		dev_err(&pdev->dev, "callback reg failed\n");
-		goto error_iio_unreg;
+		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 0;
 
-error_iio_unreg:
-	iio_device_unregister(indio_dev);
+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);
 	return ret;
@@ -389,8 +389,8 @@ static void hid_incl_3d_remove(struct platform_device *pdev)
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 	struct incl_3d_state *incl_state = iio_priv(indio_dev);
 
-	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_INCLINOMETER_3D);
 	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);
 }
 

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 3/8] iio: gyro: hid-sensor-gyro-3d: Avoid race between callback setup and device exposure
From: Sanjay Chitroda @ 2026-06-22  5:29 UTC (permalink / raw)
  To: Jiri Kosina, Jonathan Cameron, Srinivas Pandruvada, David Lechner,
	Nuno Sá, Andy Shevchenko, Archana Patni, Song Hongyan
  Cc: linux-input, linux-iio, linux-kernel, srinivas pandruvada,
	Sanjay Chitroda
In-Reply-To: <20260622-5-june-hid-iio-race-fixes-v2-0-1cfabcd1881e@gmail.com>

From: Sanjay Chitroda <sanjayembeddedse@gmail.com>

The driver currently exposes the IIO device to userspace before
completing sensor hub callback registration, and similarly removes
callbacks while the device can still be accessed during teardown.

This creates a timing window where userspace may enable the buffer
before callbacks are available. In such cases:
- samples can be dropped,
- buffered reads may observe stale or no data.

Reorder probe and remove paths to ensure callbacks are active before
device exposure and are removed after device is no longer accessible.

This avoids a race window leading to data loss.

Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
 drivers/iio/gyro/hid-sensor-gyro-3d.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c
index bbca2111e79b..c8130b488f10 100644
--- a/drivers/iio/gyro/hid-sensor-gyro-3d.c
+++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c
@@ -324,12 +324,6 @@ static int hid_gyro_3d_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = iio_device_register(indio_dev);
-	if (ret) {
-		dev_err(&pdev->dev, "device register failed\n");
-		goto error_remove_trigger;
-	}
-
 	gyro_state->callbacks.send_event = gyro_3d_proc_event;
 	gyro_state->callbacks.capture_sample = gyro_3d_capture_sample;
 	gyro_state->callbacks.pdev = pdev;
@@ -337,13 +331,19 @@ static int hid_gyro_3d_probe(struct platform_device *pdev)
 					&gyro_state->callbacks);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "callback reg failed\n");
-		goto error_iio_unreg;
+		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;
 
-error_iio_unreg:
-	iio_device_unregister(indio_dev);
+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);
 	return ret;
@@ -356,8 +356,8 @@ static void hid_gyro_3d_remove(struct platform_device *pdev)
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 	struct gyro_3d_state *gyro_state = iio_priv(indio_dev);
 
-	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_GYRO_3D);
 	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);
 }
 

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 4/8] iio: pressure: hid-sensor-press: Avoid race between callback setup and device exposure
From: Sanjay Chitroda @ 2026-06-22  5:30 UTC (permalink / raw)
  To: Jiri Kosina, Jonathan Cameron, Srinivas Pandruvada, David Lechner,
	Nuno Sá, Andy Shevchenko, Archana Patni, Song Hongyan
  Cc: linux-input, linux-iio, linux-kernel, srinivas pandruvada,
	Sanjay Chitroda
In-Reply-To: <20260622-5-june-hid-iio-race-fixes-v2-0-1cfabcd1881e@gmail.com>

From: Sanjay Chitroda <sanjayembeddedse@gmail.com>

The driver currently exposes the IIO device to userspace before
completing sensor hub callback registration, and similarly removes
callbacks while the device can still be accessed during teardown.

This creates a timing window where userspace may enable the buffer
before callbacks are available. In such cases:
- samples can be dropped,
- buffered reads may observe stale or no data.

Reorder probe and remove paths to ensure callbacks are active before
device exposure and are removed after device is no longer accessible.

This avoids a race window leading to data loss.

Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
 drivers/iio/pressure/hid-sensor-press.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/iio/pressure/hid-sensor-press.c b/drivers/iio/pressure/hid-sensor-press.c
index 3e47a10d72a8..8f81a6d65b9f 100644
--- a/drivers/iio/pressure/hid-sensor-press.c
+++ b/drivers/iio/pressure/hid-sensor-press.c
@@ -291,12 +291,6 @@ static int hid_press_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = iio_device_register(indio_dev);
-	if (ret) {
-		dev_err(&pdev->dev, "device register failed\n");
-		goto error_remove_trigger;
-	}
-
 	press_state->callbacks.send_event = press_proc_event;
 	press_state->callbacks.capture_sample = press_capture_sample;
 	press_state->callbacks.pdev = pdev;
@@ -304,13 +298,19 @@ static int hid_press_probe(struct platform_device *pdev)
 					&press_state->callbacks);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "callback reg failed\n");
-		goto error_iio_unreg;
+		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;
 
-error_iio_unreg:
-	iio_device_unregister(indio_dev);
+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);
 	return ret;
@@ -323,8 +323,8 @@ static void hid_press_remove(struct platform_device *pdev)
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 	struct press_state *press_state = iio_priv(indio_dev);
 
-	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_PRESSURE);
 	iio_device_unregister(indio_dev);
+	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_PRESSURE);
 	hid_sensor_remove_trigger(indio_dev, &press_state->common_attributes);
 }
 

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 5/8] iio: light: hid-sensor-prox: Avoid race between callback setup and device exposure
From: Sanjay Chitroda @ 2026-06-22  5:30 UTC (permalink / raw)
  To: Jiri Kosina, Jonathan Cameron, Srinivas Pandruvada, David Lechner,
	Nuno Sá, Andy Shevchenko, Archana Patni, Song Hongyan
  Cc: linux-input, linux-iio, linux-kernel, srinivas pandruvada,
	Sanjay Chitroda
In-Reply-To: <20260622-5-june-hid-iio-race-fixes-v2-0-1cfabcd1881e@gmail.com>

From: Sanjay Chitroda <sanjayembeddedse@gmail.com>

The driver currently exposes the IIO device to userspace before
completing sensor hub callback registration, and similarly removes
callbacks while the device can still be accessed during teardown.

This creates a timing window where userspace may enable the buffer
before callbacks are available. In such cases:
- samples can be dropped,
- buffered reads may observe stale or no data.

Reorder probe and remove paths to ensure callbacks are active before
device exposure and are removed after device is no longer accessible.

This avoids a race window leading to data loss.

Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
 drivers/iio/light/hid-sensor-prox.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/iio/light/hid-sensor-prox.c b/drivers/iio/light/hid-sensor-prox.c
index 9059f00f0ced..11609dc4c5dc 100644
--- a/drivers/iio/light/hid-sensor-prox.c
+++ b/drivers/iio/light/hid-sensor-prox.c
@@ -312,12 +312,6 @@ static int hid_prox_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = iio_device_register(indio_dev);
-	if (ret) {
-		dev_err(&pdev->dev, "device register failed\n");
-		goto error_remove_trigger;
-	}
-
 	prox_state->callbacks.send_event = prox_proc_event;
 	prox_state->callbacks.capture_sample = prox_capture_sample;
 	prox_state->callbacks.pdev = pdev;
@@ -325,13 +319,19 @@ static int hid_prox_probe(struct platform_device *pdev)
 					   &prox_state->callbacks);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "callback reg failed\n");
-		goto error_iio_unreg;
+		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;
 
-error_iio_unreg:
-	iio_device_unregister(indio_dev);
+error_remove_callback:
+	sensor_hub_remove_callback(hsdev, hsdev->usage);
 error_remove_trigger:
 	hid_sensor_remove_trigger(indio_dev, &prox_state->common_attributes);
 	return ret;
@@ -344,8 +344,8 @@ static void hid_prox_remove(struct platform_device *pdev)
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 	struct prox_state *prox_state = iio_priv(indio_dev);
 
-	sensor_hub_remove_callback(hsdev, hsdev->usage);
 	iio_device_unregister(indio_dev);
+	sensor_hub_remove_callback(hsdev, hsdev->usage);
 	hid_sensor_remove_trigger(indio_dev, &prox_state->common_attributes);
 }
 

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 6/8] iio: light: hid-sensor-als: Avoid race between callback setup and device exposure
From: Sanjay Chitroda @ 2026-06-22  5:30 UTC (permalink / raw)
  To: Jiri Kosina, Jonathan Cameron, Srinivas Pandruvada, David Lechner,
	Nuno Sá, Andy Shevchenko, Archana Patni, Song Hongyan
  Cc: linux-input, linux-iio, linux-kernel, srinivas pandruvada,
	Sanjay Chitroda
In-Reply-To: <20260622-5-june-hid-iio-race-fixes-v2-0-1cfabcd1881e@gmail.com>

From: Sanjay Chitroda <sanjayembeddedse@gmail.com>

The driver currently exposes the IIO device to userspace before
completing sensor hub callback registration, and similarly removes
callbacks while the device can still be accessed during teardown.

This creates a timing window where userspace may enable the buffer
before callbacks are available. In such cases:
- samples can be dropped,
- buffered reads may observe stale or no data.

Reorder probe and remove paths to ensure callbacks are active before
device exposure and are removed after device is no longer accessible.

This avoids a race window leading to data loss.

Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
 drivers/iio/light/hid-sensor-als.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c
index ae2fda8dc500..823bb56b9873 100644
--- a/drivers/iio/light/hid-sensor-als.c
+++ b/drivers/iio/light/hid-sensor-als.c
@@ -406,25 +406,25 @@ static int hid_als_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = iio_device_register(indio_dev);
-	if (ret) {
-		dev_err(&pdev->dev, "device register failed\n");
-		goto error_remove_trigger;
-	}
-
 	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);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "callback reg failed\n");
-		goto error_iio_unreg;
+		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;
 
-error_iio_unreg:
-	iio_device_unregister(indio_dev);
+error_remove_callback:
+	sensor_hub_remove_callback(hsdev, hsdev->usage);
 error_remove_trigger:
 	hid_sensor_remove_trigger(indio_dev, &als_state->common_attributes);
 	return ret;
@@ -437,8 +437,8 @@ static void hid_als_remove(struct platform_device *pdev)
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 	struct als_state *als_state = iio_priv(indio_dev);
 
-	sensor_hub_remove_callback(hsdev, hsdev->usage);
 	iio_device_unregister(indio_dev);
+	sensor_hub_remove_callback(hsdev, hsdev->usage);
 	hid_sensor_remove_trigger(indio_dev, &als_state->common_attributes);
 }
 

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 7/8] iio: magnetometer: hid-sensor-magn-3d: Avoid race between callback setup and device exposure
From: Sanjay Chitroda @ 2026-06-22  5:30 UTC (permalink / raw)
  To: Jiri Kosina, Jonathan Cameron, Srinivas Pandruvada, David Lechner,
	Nuno Sá, Andy Shevchenko, Archana Patni, Song Hongyan
  Cc: linux-input, linux-iio, linux-kernel, srinivas pandruvada,
	Sanjay Chitroda
In-Reply-To: <20260622-5-june-hid-iio-race-fixes-v2-0-1cfabcd1881e@gmail.com>

From: Sanjay Chitroda <sanjayembeddedse@gmail.com>

The driver currently exposes the IIO device to userspace before
completing sensor hub callback registration, and similarly removes
callbacks while the device can still be accessed during teardown.

This creates a timing window where userspace may enable the buffer
before callbacks are available. In such cases:
- samples can be dropped,
- buffered reads may observe stale or no data.

Reorder probe and remove paths to ensure callbacks are active before
device exposure and are removed after device is no longer accessible.

This avoids a race window leading to data loss.

Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
 drivers/iio/magnetometer/hid-sensor-magn-3d.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index 23884825eb00..acae77273bd5 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -513,12 +513,6 @@ static int hid_magn_3d_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = iio_device_register(indio_dev);
-	if (ret) {
-		dev_err(&pdev->dev, "device register failed\n");
-		goto error_remove_trigger;
-	}
-
 	magn_state->callbacks.send_event = magn_3d_proc_event;
 	magn_state->callbacks.capture_sample = magn_3d_capture_sample;
 	magn_state->callbacks.pdev = pdev;
@@ -526,13 +520,19 @@ static int hid_magn_3d_probe(struct platform_device *pdev)
 					&magn_state->callbacks);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "callback reg failed\n");
-		goto error_iio_unreg;
+		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;
 
-error_iio_unreg:
-	iio_device_unregister(indio_dev);
+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);
 	return ret;
@@ -545,8 +545,8 @@ static void hid_magn_3d_remove(struct platform_device *pdev)
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 	struct magn_3d_state *magn_state = iio_priv(indio_dev);
 
-	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_COMPASS_3D);
 	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);
 }
 

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 8/8] iio: accel: hid-sensor-accel-3d: Avoid race between callback setup and device exposure
From: Sanjay Chitroda @ 2026-06-22  5:30 UTC (permalink / raw)
  To: Jiri Kosina, Jonathan Cameron, Srinivas Pandruvada, David Lechner,
	Nuno Sá, Andy Shevchenko, Archana Patni, Song Hongyan
  Cc: linux-input, linux-iio, linux-kernel, srinivas pandruvada,
	Sanjay Chitroda
In-Reply-To: <20260622-5-june-hid-iio-race-fixes-v2-0-1cfabcd1881e@gmail.com>

From: Sanjay Chitroda <sanjayembeddedse@gmail.com>

The driver currently exposes the IIO device to userspace before
completing sensor hub callback registration, and similarly removes
callbacks while the device can still be accessed during teardown.

This creates a timing window where userspace may enable the buffer
before callbacks are available. In such cases:
- samples can be dropped,
- buffered reads may observe stale or no data.

Reorder probe and remove paths to ensure callbacks are active before
device exposure and are removed after device is no longer accessible.

This avoids a race window leading to data loss.

Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
---
 drivers/iio/accel/hid-sensor-accel-3d.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c
index 42c4259bf209..12481cfe9800 100644
--- a/drivers/iio/accel/hid-sensor-accel-3d.c
+++ b/drivers/iio/accel/hid-sensor-accel-3d.c
@@ -386,12 +386,6 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = iio_device_register(indio_dev);
-	if (ret) {
-		dev_err(&pdev->dev, "device register failed\n");
-		goto error_remove_trigger;
-	}
-
 	accel_state->callbacks.send_event = accel_3d_proc_event;
 	accel_state->callbacks.capture_sample = accel_3d_capture_sample;
 	accel_state->callbacks.pdev = pdev;
@@ -399,13 +393,19 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
 					&accel_state->callbacks);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "callback reg failed\n");
-		goto error_iio_unreg;
+		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;
 
-error_iio_unreg:
-	iio_device_unregister(indio_dev);
+error_remove_callback:
+	sensor_hub_remove_callback(hsdev, hsdev->usage);
 error_remove_trigger:
 	hid_sensor_remove_trigger(indio_dev, &accel_state->common_attributes);
 	return ret;
@@ -418,8 +418,8 @@ static void hid_accel_3d_remove(struct platform_device *pdev)
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 	struct accel_3d_state *accel_state = iio_priv(indio_dev);
 
-	sensor_hub_remove_callback(hsdev, hsdev->usage);
 	iio_device_unregister(indio_dev);
+	sensor_hub_remove_callback(hsdev, hsdev->usage);
 	hid_sensor_remove_trigger(indio_dev, &accel_state->common_attributes);
 }
 

-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH v1] iio: temperature: hid-sensor-temperature: switch to non-devm iio_device_register()
From: sashiko-bot @ 2026-06-22  5:39 UTC (permalink / raw)
  To: Sanjay Chitroda; +Cc: dmitry.torokhov, linux-input
In-Reply-To: <20260622052135.1804135-1-sanjayembedded@gmail.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Pre-existing issues:
- [Critical] Concurrent execution of HID sensor hub callbacks and device unbind leads to a Use-After-Free of `indio_dev`.
- [High] The static global `temperature_callbacks` struct is mutated during probe, causing data corruption and cross-device routing bugs when multiple sensors are present.
--

commit 829c19b8a370c5d8b09345d4e07b865deb47a88f
Author: Sanjay Chitroda <sanjayembeddedse@gmail.com>

iio: temperature: hid-sensor-temperature: switch to non-devm iio_device_register()

This commit replaces devm_iio_device_register() with iio_device_register() 
to ensure deterministic cleanup. It adds an explicit iio_device_unregister() 
call in the remove path to fix potential use-after-free race conditions 
during device removal.

> diff --git a/drivers/iio/temperature/hid-sensor-temperature.c b/drivers/iio/temperature/hid-sensor-temperature.c
> index 9f628a8e5cfbe..34bff7e9f3a33 100644
> --- a/drivers/iio/temperature/hid-sensor-temperature.c
> +++ b/drivers/iio/temperature/hid-sensor-temperature.c
> @@ -244,7 +244,7 @@ static int hid_temperature_probe(struct platform_device *pdev)
>  	if (ret)
>  		goto error_remove_trigger;
>  
> -	ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev);
> +	ret = iio_device_register(indio_dev);

[Severity: High]
This isn't a bug introduced by this patch, but looking at the probe function
just prior to this registration, is there a risk of corrupting device routing
when multiple sensors are present?

The driver defines temperature_callbacks as a static global struct:

static struct hid_sensor_hub_callbacks temperature_callbacks = {
        .send_event = &temperature_proc_event,
        .capture_sample = &temperature_capture_sample,
};

During hid_temperature_probe(), the current device's pdev is directly
assigned to temperature_callbacks.pdev.

If a system has multiple HID temperature sensors, does the last probed sensor
overwrite this global pointer? It seems like when sensor_hub_raw_event()
processes hardware events, it might fetch the shared struct and pass the
single overwritten pdev to temperature_capture_sample(). Would this cause the
data from all temperature sensors to be written exclusively into the IIO state
of the last probed sensor?

[ ... ]

> @@ -264,6 +264,7 @@ static void hid_temperature_remove(struct platform_device *pdev)
>  	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>  	struct temperature_state *temp_st = iio_priv(indio_dev);
>  
> +	iio_device_unregister(indio_dev);
>  	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TEMPERATURE);

[Severity: Critical]
This is a pre-existing issue, but I wanted to ask about the teardown order
here.

In hid_temperature_remove(), we call sensor_hub_remove_callback(), which
removes the callback from the sensor hub's list under dyn_callback_lock.
However, it doesn't appear to synchronize with or wait for concurrently
executing callback handlers like sensor_hub_raw_event() to finish before
returning.

Since indio_dev is allocated with devm_iio_device_alloc() during probe, it
will be freed by devres immediately after hid_temperature_remove() returns.

If sensor_hub_raw_event() is executing concurrently and has already retrieved
the callback pointer, could it pass the pdev to temperature_capture_sample()
and perform a use-after-free write on the freed private state?

For example:
temp_st->scan.temperature_data = *(s32 *)raw_data;

Should we be flushing or waiting for running callbacks to complete before
letting the device context be freed?

>  	hid_sensor_remove_trigger(indio_dev, &temp_st->common_attributes);
>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260622052135.1804135-1-sanjayembedded@gmail.com?part=1

^ permalink raw reply

* Re: [PATCH v2 5/8] iio: light: hid-sensor-prox: Avoid race between callback setup and device exposure
From: sashiko-bot @ 2026-06-22  5:42 UTC (permalink / raw)
  To: Sanjay Chitroda; +Cc: dmitry.torokhov, linux-input
In-Reply-To: <20260622-5-june-hid-iio-race-fixes-v2-5-1cfabcd1881e@gmail.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

New issues:
- [Critical] The reordering introduces a Use-After-Free race condition in the probe error path due to a lack of synchronization when removing the callback.
- [Critical] Reordering `sensor_hub_remove_callback()` after `iio_device_unregister()` creates a severe race condition where lockless list traversal races with IIO buffer teardown, potentially causing an infinite loop.

Pre-existing issues:
- [Critical] Preexisting Use-After-Free in the device remove path due to lack of callback synchronization.
--

commit a4fd8cfbe15835905bbb5054997cb2a8715dcdd2
Author: Sanjay Chitroda <sanjayembeddedse@gmail.com>

iio: light: hid-sensor-prox: Avoid race between callback setup and device exposure

The driver currently exposes the IIO device to userspace before completing
sensor hub callback registration, and similarly removes callbacks while the
device can still be accessed during teardown. This reorders probe and remove
paths to avoid a race window.

> diff --git a/drivers/iio/light/hid-sensor-prox.c b/drivers/iio/light/hid-sensor-prox.c
> index 9059f00f0cedf..11609dc4c5dc6 100644
> --- a/drivers/iio/light/hid-sensor-prox.c
> +++ b/drivers/iio/light/hid-sensor-prox.c

[ ... ]

> @@ -325,13 +319,19 @@ static int hid_prox_probe(struct platform_device *pdev)
>  					   &prox_state->callbacks);
>  	if (ret < 0) {
>  		dev_err(&pdev->dev, "callback reg failed\n");
> -		goto error_iio_unreg;
> +		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;
>  
> -error_iio_unreg:
> -	iio_device_unregister(indio_dev);
> +error_remove_callback:
> +	sensor_hub_remove_callback(hsdev, hsdev->usage);

[Severity: Critical]
Could this introduce a use-after-free if the callback fires during error
handling?

Looking at sensor_hub_remove_callback(), it unlinks the callback from the
list but does not appear to wait for actively executing handlers to finish.
If a sensor event triggers concurrently, hid_prox_probe() could return,
allowing the devres framework to free the indio_dev and prox_state memory.

Would an actively executing callback then dereference this freed memory?

>  error_remove_trigger:
>  	hid_sensor_remove_trigger(indio_dev, &prox_state->common_attributes);
>  	return ret;
> @@ -344,8 +344,8 @@ static void hid_prox_remove(struct platform_device *pdev)
>  	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>  	struct prox_state *prox_state = iio_priv(indio_dev);
>  
> -	sensor_hub_remove_callback(hsdev, hsdev->usage);
>  	iio_device_unregister(indio_dev);
> +	sensor_hub_remove_callback(hsdev, hsdev->usage);

[Severity: Critical]
Does reordering these calls create a race condition with IIO buffer teardown?

By unregistering the IIO device before removing the sensor hub callback, a
concurrently firing callback could invoke iio_push_to_buffers() while
iio_device_unregister() is tearing down the buffers.

iio_push_to_buffers() traverses the buffer list locklessly:

    list_for_each_entry(buf, &iio_dev_opaque->buffer_list, buffer_list) {

At the same time, iio_device_unregister() modifies this list using
list_del_init() via iio_buffer_deactivate(). If the lockless iterator
evaluates a buffer node exactly when list_del_init() resets its pointers to
point to itself, could this cause an endless loop and a hard CPU stall?

[Severity: Critical]
This is a pre-existing issue, but does sensor_hub_remove_callback() properly
synchronize with active callbacks before returning?

Since sensor_hub_remove_callback() unlinks the callback but does not wait
for executions of sensor_hub_raw_event() to finish, hid_prox_remove() can
return while callbacks are still running.

Once the function returns, the devres framework frees indio_dev and
prox_state. Can this lead to a use-after-free when the still-running
callback attempts to access the freed memory?

>  	hid_sensor_remove_trigger(indio_dev, &prox_state->common_attributes);
>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260622-5-june-hid-iio-race-fixes-v2-0-1cfabcd1881e@gmail.com?part=5

^ permalink raw reply

* Re: [PATCH v2 1/8] iio: orientation: hid-sensor-rotation: Avoid race between callback setup and device exposure
From: sashiko-bot @ 2026-06-22  5:42 UTC (permalink / raw)
  To: Sanjay Chitroda; +Cc: linux-input, dmitry.torokhov
In-Reply-To: <20260622-5-june-hid-iio-race-fixes-v2-1-1cfabcd1881e@gmail.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

New issues:
- [High] Reordering `iio_device_unregister()` before `sensor_hub_remove_callback()` creates a TOCTOU race condition that can lead to IIO buffer list corruption and infinite loops.

Pre-existing issues:
- [High] Concurrent execution of sensor hub callbacks can cause use-after-free on probe failure or device removal due to lack of synchronization.
- [High] Malicious or malformed HID devices can trigger an out-of-bounds read of kernel memory due to a lack of bounds checking on the raw data buffer.
--

commit 3524bf526c21d398ff01cdcd77d3cff858988d72
Author: Sanjay Chitroda <sanjayembeddedse@gmail.com>

iio: orientation: hid-sensor-rotation: Avoid race between callback setup and device exposure

This patch reorders the probe and remove paths in the hid-sensor-rotation
driver to ensure sensor hub callbacks are registered before the IIO device
is exposed, and removed after the device is unregistered. This aims to
prevent userspace from accessing the device before callbacks are ready.

> diff --git a/drivers/iio/orientation/hid-sensor-rotation.c b/drivers/iio/orientation/hid-sensor-rotation.c
> --- a/drivers/iio/orientation/hid-sensor-rotation.c
> +++ b/drivers/iio/orientation/hid-sensor-rotation.c

[ ... ]

> @@ -345,13 +339,19 @@ 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;

[Severity: High]
This isn't a bug introduced by this patch, but does dev_rot_capture_sample()
lack bounds checking on the raw data buffer?

If a maliciously crafted HID descriptor specifies a small size (e.g., 4 bytes)
for the quaternion field, the HID core will allocate a buffer matching that
small size.

In dev_rot_capture_sample(), if the size doesn't match the expected 16 bytes,
it falls back to a blind copy:

        } else {
                memcpy(&rot_state->scan.sampled_vals, raw_data,
                       sizeof(rot_state->scan.sampled_vals));
        }

Since sizeof(rot_state->scan.sampled_vals) is 16 bytes, this reads past the
end of a smaller raw_data buffer and copies adjacent kernel heap memory into
the IIO buffer. Userspace can then read this IIO buffer, resulting in an
information leak.

>  	rot_state->callbacks.pdev = pdev;
>  	ret = sensor_hub_register_callback(hsdev, hsdev->usage,
>  					&rot_state->callbacks);
>  	if (ret) {
>  		dev_err(&pdev->dev, "callback reg failed\n");
> -		goto error_iio_unreg;
> +		goto error_remove_trigger;
> +	}
> +
> +	ret = iio_device_register(indio_dev);
> +	if (ret) {
>  		dev_err(&pdev->dev, "device register failed\n");
> -		goto error_remove_trigger;
> -	}
>  
>  	return 0;
>  
> -error_iio_unreg:
> -	iio_device_unregister(indio_dev);
> +error_remove_callback:
> +	sensor_hub_remove_callback(hsdev, hsdev->usage);

[Severity: High]
This is a pre-existing issue, but does removing the callback here leave a
window for a use-after-free?

sensor_hub_raw_event() looks up a callback and executes it under pdata->lock.
However, sensor_hub_remove_callback() removes the callback from
pdata->dyn_callback_list without waiting for any currently executing
callbacks in sensor_hub_raw_event() to complete.

If a callback is executing concurrently on another CPU when probe fails or
the device is removed, the driver will exit and devres will free the
indio_dev and rot_state memory structures. The still-executing callback
will then continue reading and writing to the freed rot_state fields.

>  error_remove_trigger:
>  	hid_sensor_remove_trigger(indio_dev, &rot_state->common_attributes);
>  	return ret;
> @@ -364,8 +364,8 @@ static void hid_dev_rot_remove(struct platform_device *pdev)
>  	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>  	struct dev_rot_state *rot_state = iio_priv(indio_dev);
>  
> -	sensor_hub_remove_callback(hsdev, hsdev->usage);
>  	iio_device_unregister(indio_dev);
> +	sensor_hub_remove_callback(hsdev, hsdev->usage);

[Severity: High]
Does reordering iio_device_unregister() before sensor_hub_remove_callback()
create a race condition that can lead to an infinite loop?

iio_device_unregister() disables all buffers, which calls list_del_init() on
the buffer list under the IIO core info_exist_lock. If the sensor hub
callback has not been removed yet, a hardware interrupt can still trigger
the callback, which calls dev_rot_proc_event() and subsequently
iio_push_to_buffers().
        
iio_push_to_buffers() iterates over the buffer list locklessly using
list_for_each_entry(). If list_del_init() executes concurrently with this
lockless iteration, the 'next' pointer of the removed list element points
to itself. This causes the lockless iterator to enter an infinite loop and
hang the kernel.

Should the data producer (the callback) be stopped before destroying the
data consumer (unregistering the IIO device)?

>  	hid_sensor_remove_trigger(indio_dev, &rot_state->common_attributes);
>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260622-5-june-hid-iio-race-fixes-v2-0-1cfabcd1881e@gmail.com?part=1

^ permalink raw reply

* Re: [PATCH v2 4/8] iio: pressure: hid-sensor-press: Avoid race between callback setup and device exposure
From: sashiko-bot @ 2026-06-22  5:44 UTC (permalink / raw)
  To: Sanjay Chitroda; +Cc: linux-input, dmitry.torokhov
In-Reply-To: <20260622-5-june-hid-iio-race-fixes-v2-4-1cfabcd1881e@gmail.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

New issues:
- [High] Reordering `iio_device_unregister()` before `sensor_hub_remove_callback()` introduces a race condition leading to list corruption or Use-After-Free.

Pre-existing issues:
- [High] Lack of synchronization in `sensor_hub_remove_callback()` allows concurrent events to cause a Use-After-Free in the probe error path and device removal.
- [High] Unaligned and out-of-bounds memory access in `press_capture_sample()`.
--

commit 9b0142efc7c55a69dc83b67a2c132e1f174fd7cc
Author: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Subject: iio: pressure: hid-sensor-press: Avoid race between callback setup and device exposure

This patch reorders the probe and remove paths in the hid-sensor-press
driver. It registers the sensor hub callbacks before exposing the IIO
device to userspace, and in reverse during teardown, intending to fix
timing windows where buffers might be accessed before callbacks are ready.

> diff --git a/drivers/iio/pressure/hid-sensor-press.c b/drivers/iio/pressure/hid-sensor-press.c
> index 3e47a10d72a89..8f81a6d65b9f7 100644
> --- a/drivers/iio/pressure/hid-sensor-press.c
> +++ b/drivers/iio/pressure/hid-sensor-press.c

[ ... ]

> @@ -304,13 +298,19 @@ static int hid_press_probe(struct platform_device *pdev)
>  					&press_state->callbacks);
>  	if (ret < 0) {
>  		dev_err(&pdev->dev, "callback reg failed\n");
> -		goto error_iio_unreg;
> +		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;
>  
> -error_iio_unreg:
> -	iio_device_unregister(indio_dev);
> +error_remove_callback:
> +	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_PRESSURE);

[Severity: High]
This is a pre-existing issue, but does sensor_hub_remove_callback() wait
for any executing callbacks to complete?

If iio_device_register() fails, the new error path calls
sensor_hub_remove_callback(). If a callback like press_proc_event() is
already running concurrently, it appears the memory for press_state will be
freed by devres while the callback is still dereferencing it, potentially
leading to a use-after-free.

>  error_remove_trigger:
>  	hid_sensor_remove_trigger(indio_dev, &press_state->common_attributes);
>  	return ret;
> @@ -323,8 +323,8 @@ static void hid_press_remove(struct platform_device *pdev)
>  	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>  	struct press_state *press_state = iio_priv(indio_dev);
>  
> -	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_PRESSURE);
>  	iio_device_unregister(indio_dev);
> +	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_PRESSURE);

[Severity: High]
Does unregistering the IIO device before removing the sensor hub callback
introduce a regression during teardown?

By explicitly reversing the teardown order, iio_device_unregister() will
dismantle the IIO buffers via iio_disable_all_buffers(). If a hardware
event arrives concurrently, the still-active press_proc_event() callback can
call iio_push_to_buffers_with_ts() and attempt to push data to buffers being
locklessly destroyed, which could lead to list corruption or a
use-after-free.

>  	hid_sensor_remove_trigger(indio_dev, &press_state->common_attributes);
>  }

[Severity: High]
This isn't a bug introduced by this patch, but is press_capture_sample()
safely handling the raw_data buffer?

Looking at the callback handling in press_capture_sample():

drivers/iio/pressure/hid-sensor-press.c:press_capture_sample() {
	...
	switch (usage_id) {
	case HID_USAGE_SENSOR_ATMOSPHERIC_PRESSURE:
		press_state->scan.press_data = *(u32 *)raw_data;
        ...
}

The pointer raw_data is directly cast to u32 * and dereferenced without
verifying raw_len or checking for proper alignment.

Could a maliciously crafted HID descriptor with a shorter report length
cause an out-of-bounds read that leaks heap memory to userspace, or trigger
unaligned access faults on architectures that strictly require alignment?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260622-5-june-hid-iio-race-fixes-v2-0-1cfabcd1881e@gmail.com?part=4

^ permalink raw reply

* Re: [PATCH v2 3/8] iio: gyro: hid-sensor-gyro-3d: Avoid race between callback setup and device exposure
From: sashiko-bot @ 2026-06-22  5:45 UTC (permalink / raw)
  To: Sanjay Chitroda; +Cc: dmitry.torokhov, linux-input
In-Reply-To: <20260622-5-june-hid-iio-race-fixes-v2-3-1cfabcd1881e@gmail.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

New issues:
- [Critical] Reordering `iio_device_unregister()` to execute before `sensor_hub_remove_callback()` introduces a critical race condition leading to list corruption or an infinite loop.
- [High] The patch introduces a use-after-free vulnerability on the probe error path if `iio_device_register()` fails.

Pre-existing issues:
- [Critical] A preexisting architectural flaw in the `hid-sensor-hub` framework allows a use-after-free if a raw event is processed during driver removal.
--

commit 081315902ee73f264b09ca59da9c7688bdfeefd0
Author: Sanjay Chitroda <sanjayembeddedse@gmail.com>

iio: gyro: hid-sensor-gyro-3d: Avoid race between callback setup and device exposure

The driver currently exposes the IIO device to userspace before
completing sensor hub callback registration, and similarly removes
callbacks while the device can still be accessed during teardown.

> diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c
> index bbca2111e79bb..c8130b488f103 100644
> --- a/drivers/iio/gyro/hid-sensor-gyro-3d.c
> +++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c

[ ... ]

> @@ -337,13 +331,19 @@ static int hid_gyro_3d_probe(struct platform_device *pdev)
>  					&gyro_state->callbacks);
>  	if (ret < 0) {
>  		dev_err(&pdev->dev, "callback reg failed\n");
> -		goto error_iio_unreg;
> +		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;
>  
> -error_iio_unreg:
> -	iio_device_unregister(indio_dev);
> +error_remove_callback:
> +	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_GYRO_3D);

[Severity: High]
Does this error path introduce a use-after-free vulnerability?

By moving sensor_hub_register_callback() to execute before
iio_device_register(), if device registration fails, the new error path
removes the callback and returns.

However, sensor_hub_remove_callback() does not wait for concurrently
executing callbacks to finish. If an incoming hardware event triggers
gyro_3d_proc_event() on another CPU right after registration, and then
probe returns, devres will automatically free indio_dev (which contains
gyro_state). The still-executing callback would then dereference the freed
memory.

Could this be prevented by ensuring the callback is only registered when it
is safe to process events?

[Severity: Critical]
This isn't a bug introduced by this patch, but there is a pre-existing
architectural flaw in the hid-sensor-hub framework that exacerbates this
teardown race.

Looking at sensor_hub_remove_callback(), it removes a sensor's callback from
dyn_callback_list under a lock, then immediately returns without waiting for
sensor_hub_raw_event() handlers executing on other CPUs to complete.

Because sensor_hub_raw_event() temporarily drops the list lock and invokes the
driver's function pointers based on a cached pointer, if driver removal or
probe failure completes while this is executing, devres frees the driver
memory. The framework then continues to dereference the cached callback
pointer into freed memory.

Would it be possible to add proper synchronization, such as a completion or
RCU sync, in the sensor_hub_remove_callback() framework to prevent this?

> @@ -356,8 +356,8 @@ static void hid_gyro_3d_remove(struct platform_device *pdev)
>  	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>  	struct gyro_3d_state *gyro_state = iio_priv(indio_dev);
>  
> -	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_GYRO_3D);
>  	iio_device_unregister(indio_dev);
> +	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_GYRO_3D);

[Severity: Critical]
Does reordering these functions introduce a race condition that leads to list
corruption or an infinite loop?

iio_device_unregister() disables IIO buffers and dismantles the buffer list
locklessly using list_del_init(). If we call iio_device_unregister() while
the sensor hub callback is still active, incoming hardware events can still
trigger gyro_3d_proc_event().

gyro_3d_proc_event() calls iio_push_to_buffers_with_timestamp(), which
iterates over the buffer list locklessly:

gyro_3d_proc_event()
   iio_push_to_buffers_with_timestamp()
      list_for_each_entry()

Because list_del_init() points the next pointer to itself, traversing the list
concurrently while it is being dismantled could cause the loop to never
terminate, resulting in a hard CPU hang.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260622-5-june-hid-iio-race-fixes-v2-0-1cfabcd1881e@gmail.com?part=3

^ permalink raw reply

* Re: [PATCH v2 6/8] iio: light: hid-sensor-als: Avoid race between callback setup and device exposure
From: sashiko-bot @ 2026-06-22  5:45 UTC (permalink / raw)
  To: Sanjay Chitroda; +Cc: dmitry.torokhov, linux-input
In-Reply-To: <20260622-5-june-hid-iio-race-fixes-v2-6-1cfabcd1881e@gmail.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] Use-After-Free due to lack of synchronization in sensor_hub_remove_callback()
--

commit 74625485fbdc50663ffbe0a0e45aa978eaafe03d
Author: Sanjay Chitroda <sanjayembeddedse@gmail.com>

iio: light: hid-sensor-als: Avoid race between callback setup and device exposure

The driver currently exposes the IIO device to userspace before completing
sensor hub callback registration, and similarly removes callbacks while the
device can still be accessed during teardown. Reorder probe and remove paths to
ensure callbacks are active before device exposure and are removed after device
is no longer accessible.

> diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c
> index ae2fda8dc500a..823bb56b9873a 100644
> --- a/drivers/iio/light/hid-sensor-als.c
> +++ b/drivers/iio/light/hid-sensor-als.c
> @@ -406,25 +406,25 @@ static int hid_als_probe(struct platform_device *pdev)

[ ... ]

> -	ret = iio_device_register(indio_dev);
> -	if (ret) {
> -		dev_err(&pdev->dev, "device register failed\n");
> -		goto error_remove_trigger;
> -	}
> -
>  	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);
>  	if (ret < 0) {
>  		dev_err(&pdev->dev, "callback reg failed\n");
> -		goto error_iio_unreg;
> +		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;
>  
> -error_iio_unreg:
> -	iio_device_unregister(indio_dev);
> +error_remove_callback:
> +	sensor_hub_remove_callback(hsdev, hsdev->usage);

[Severity: High]
This is a pre-existing issue, but can this lead to a use-after-free if
sensor_hub_raw_event() is executing concurrently?

When iio_device_register() fails, we call sensor_hub_remove_callback() in the
new error path. Looking at sensor_hub_remove_callback() in
drivers/hid/hid-sensor-hub.c, it removes the callback list entry under
dyn_callback_lock and returns immediately without synchronizing with any
currently executing events:

drivers/hid/hid-sensor-hub.c:sensor_hub_remove_callback() {
    ...
		if (callback->usage_id == usage_id &&
						callback->hsdev == hsdev) {
			list_del(&callback->list);
			kfree(callback);
			break;
		}
	spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
    ...
}

However, sensor_hub_raw_event() drops dyn_callback_lock before executing
the callbacks:

drivers/hid/hid-sensor-hub.c:sensor_hub_raw_event() {
    ...
				callback->capture_sample(hsdev,
					report->field[i]->usage->hid, sz, ptr,
					callback->pdev);
    ...
}

If sensor_hub_raw_event() is running concurrently when we return from
hid_als_probe(), devres will automatically free the IIO device and als_state.
Would the concurrently executing event handler then access freed memory?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260622-5-june-hid-iio-race-fixes-v2-0-1cfabcd1881e@gmail.com?part=6

^ permalink raw reply

* Re: [PATCH v2 2/8] iio: orientation: hid-sensor-incl-3d: Avoid race between callback setup and device exposure
From: sashiko-bot @ 2026-06-22  5:46 UTC (permalink / raw)
  To: Sanjay Chitroda; +Cc: linux-input, dmitry.torokhov
In-Reply-To: <20260622-5-june-hid-iio-race-fixes-v2-2-1cfabcd1881e@gmail.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

New issues:
- [High] Reordering `iio_device_unregister()` before `sensor_hub_remove_callback()` introduces a race condition leading to list corruption and use-after-free.

Pre-existing issues:
- [High] `sensor_hub_remove_callback()` does not wait for concurrently executing callbacks to finish, leading to Use-After-Free.
- [High] Out-Of-Bounds read in `incl_3d_capture_sample` due to lack of `raw_len` bounds checking.
--

commit 4947d2a547210c33e3a2154a81959edb205f29de
Author: Sanjay Chitroda <sanjayembeddedse@gmail.com>

iio: orientation: hid-sensor-incl-3d: Avoid race between callback setup and device exposure

This commit reorders the probe and remove paths for the incl-3d sensor driver.
It aims to ensure callbacks are registered before device registration and
removed after device unregistration, closing a timing window where userspace
might enable the buffer before callbacks are available.

> diff --git a/drivers/iio/orientation/hid-sensor-incl-3d.c b/drivers/iio/orientation/hid-sensor-incl-3d.c
> index c7fbff498be7a..5696e4ef36334 100644
> --- a/drivers/iio/orientation/hid-sensor-incl-3d.c
> +++ b/drivers/iio/orientation/hid-sensor-incl-3d.c
[ ... ]
> @@ -370,13 +364,19 @@ static int hid_incl_3d_probe(struct platform_device *pdev)
>  					&incl_state->callbacks);
>  	if (ret) {
>  		dev_err(&pdev->dev, "callback reg failed\n");
> -		goto error_iio_unreg;
> +		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 0;
>  
> -error_iio_unreg:
> -	iio_device_unregister(indio_dev);
> +error_remove_callback:
> +	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_INCLINOMETER_3D);

[Severity: High]
This is a pre-existing issue, but does sensor_hub_remove_callback() wait for
currently executing callbacks to finish?

When sensor_hub_remove_callback() is called here or during device removal, it
removes the callback from the internal list under a spinlock but doesn't
appear to synchronize with event handlers executing on another CPU.

Since the devres subsystem subsequently frees the memory containing incl_state,
could a concurrently executing callback dereference the freed memory, leading
to a use-after-free?

>  error_remove_trigger:
>  	hid_sensor_remove_trigger(indio_dev, &incl_state->common_attributes);
>  	return ret;
> @@ -389,8 +389,8 @@ static void hid_incl_3d_remove(struct platform_device *pdev)
>  	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>  	struct incl_3d_state *incl_state = iio_priv(indio_dev);
>  
> -	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_INCLINOMETER_3D);
>  	iio_device_unregister(indio_dev);
> +	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_INCLINOMETER_3D);

[Severity: High]
Does this reordering introduce a race condition leading to list corruption
and a use-after-free?

If iio_device_unregister() executes while the HID sensor callback is still
actively registered, iio_disable_all_buffers() will locklessly clear the
buffer_list using list_del_init().

Because the hardware is not synchronously powered down, incoming events can
continue to trigger incl_3d_proc_event(), which calls
iio_push_to_buffers_with_timestamp().

Since iio_push_to_buffers_with_timestamp() uses a lockless
list_for_each_entry loop to traverse the same buffer_list:

drivers/iio/industrialio-buffer.c:iio_push_to_buffers() {
    ...
    list_for_each_entry(buf, &iio_dev_opaque->buffer_list, buffer_list) {
    ...
}

won't modifying this list concurrently cause list corruption or a panic?

>  	hid_sensor_remove_trigger(indio_dev, &incl_state->common_attributes);
>  }

[Severity: High]
This is a pre-existing issue, but does incl_3d_capture_sample() check the
raw_len bounds before dereferencing raw_data?

drivers/iio/orientation/hid-sensor-incl-3d.c:incl_3d_capture_sample() {
    ...
    incl_state->scan.incl_val[CHANNEL_SCAN_INDEX_X] = *(u32 *)raw_data;
    ...
}

If a malicious USB HID device or a userspace program using uhid advertises a
custom HID descriptor with a field size of 1 byte, could dereferencing
raw_data as a 32-bit or 64-bit integer read past the end of the field and
leak kernel heap memory into the IIO buffer?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260622-5-june-hid-iio-race-fixes-v2-0-1cfabcd1881e@gmail.com?part=2

^ permalink raw reply

* Re: [PATCH v2 7/8] iio: magnetometer: hid-sensor-magn-3d: Avoid race between callback setup and device exposure
From: sashiko-bot @ 2026-06-22  5:50 UTC (permalink / raw)
  To: Sanjay Chitroda; +Cc: linux-input, dmitry.torokhov
In-Reply-To: <20260622-5-june-hid-iio-race-fixes-v2-7-1cfabcd1881e@gmail.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

New issues:
- [High] Reversing teardown order introduces severe race condition leading to list corruption and use-after-free.
- [High] Reordering probe sequence introduces a Use-After-Free (UAF) vulnerability on the error path.

Pre-existing issues:
- [High] Direct unaligned and out-of-bounds dereference of `raw_data` buffer.
--

commit 88cf07ac8710a7390dc946776d5f89db30869a24
Author: Sanjay Chitroda <sanjayembeddedse@gmail.com>

iio: magnetometer: hid-sensor-magn-3d: Avoid race between callback setup and device exposure

The driver currently exposes the IIO device to userspace before
completing sensor hub callback registration, and similarly removes
callbacks while the device can still be accessed during teardown.

> diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
> --- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
> +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
[ ... ]
> @@ -526,13 +520,19 @@ static int hid_magn_3d_probe(struct platform_device *pdev)
>  					&magn_state->callbacks);
>  	if (ret < 0) {
>  		dev_err(&pdev->dev, "callback reg failed\n");
> -		goto error_iio_unreg;
> +		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;
>  
> -error_iio_unreg:
> -	iio_device_unregister(indio_dev);
> +error_remove_callback:
> +	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_COMPASS_3D);

[Severity: High]
If iio_device_register() fails, does this error path allow a use-after-free
if a concurrent HID event is processing?

sensor_hub_remove_callback() removes the callback from the list lock, but it
does not synchronize with currently executing events. If an event is executing
inside sensor_hub_raw_event() calling magn_3d_capture_sample(), and we return
an error here, devres will immediately free the indio_dev and magn_state memory.

Could the still-executing callback dereference freed memory?

>  error_remove_trigger:
>  	hid_sensor_remove_trigger(indio_dev, &magn_state->magn_flux_attributes);
>  	return ret;
> @@ -545,8 +545,8 @@ static void hid_magn_3d_remove(struct platform_device *pdev)
>  	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>  	struct magn_3d_state *magn_state = iio_priv(indio_dev);
>  
> -	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_COMPASS_3D);
>  	iio_device_unregister(indio_dev);
> +	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_COMPASS_3D);

[Severity: High]
Does changing this teardown order introduce list corruption?

iio_device_unregister() disables IIO buffers, which iterates and modifies
the IIO device's buffer_list using list_del_init(). Because the callback
is still active here, a concurrent hardware event can invoke
magn_3d_proc_event() which calls iio_push_to_buffers_with_timestamp().

iio_push_to_buffers_with_timestamp() iterates the exact same buffer_list
locklessly. Can iterating this linked list concurrently with node deletion
cause list corruption and an eventual use-after-free?

>  	hid_sensor_remove_trigger(indio_dev, &magn_state->magn_flux_attributes);
>  }

[ ... ]

[Severity: High]
This isn't a bug introduced by this patch, but I noticed a potential alignment
and out-of-bounds problem in magn_3d_capture_sample():

magn_3d_capture_sample() {
    ...
    magn_state->timestamp =
        hid_sensor_convert_timestamp(&magn_state->magn_flux_attributes,
                                     *(s64 *)raw_data);
    ...
}

Does casting the raw_data buffer directly to an s64 pointer guarantee
alignment and bounds safety?

Since raw_data points directly into the parsed HID report, it might not be
8-byte aligned, which could cause an alignment fault on architectures that
do not support hardware unaligned access.

Additionally, if the device hardware reports a smaller data length (such as a
32-bit timestamp), dereferencing it as an s64 will read past the valid
boundaries of the HID report payload.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260622-5-june-hid-iio-race-fixes-v2-0-1cfabcd1881e@gmail.com?part=7

^ permalink raw reply

* Re: [PATCH bpf-next v2 2/2] selftests/hid: Cover hid_bpf_get_data() size overflow
From: Yiyang Chen @ 2026-06-22  5:50 UTC (permalink / raw)
  To: bot+bpf-ci
  Cc: andrii, ast, bentiss, bpf, chenyy23, clm, daniel, eddyz87,
	ihor.solodrai, jikos, jolsa, linux-input, linux-kernel,
	linux-kselftest, martin.lau, martin.lau, memxor, shuah, song,
	yonghong.song
In-Reply-To: <b3b148b42eb198ac7194c1c0547e47275b9f5d31133eececaf1389f17caed5af@mail.kernel.org>

On Sat, Jun 20, 2026 at 03:11:00PM +0000, bot+bpf-ci@kernel.org wrote:
> That wrapping check was introduced in 658ee5a64fcf, and the fix commit
> carries a Fixes: tag for it. Should this test commit carry the same tag?
>
>   Fixes: 658ee5a64fcf ("HID: bpf: allocate data memory for device_event BPF programs")

Yes, I will add the same Fixes tag to the selftest patch in v3 so the
regression test is tied to the commit that introduced the wrapping check.

> This was raised on an earlier posting and does not look addressed:
> the callback stores the result in the get_data_overflow_check global
> and always returns 0, while the userspace test asserts on that global
> rather than on the callback return value.
>
> Could the callback just return the helper result so the test can check
> the return value directly, instead of routing it through a separate
> global?

The callback's return value is not something the test can observe
directly.  call_hid_bpf_rdesc_fixup() consumes it as a kernel-side
contract: a negative value falls back to the original report descriptor,
and a positive value becomes the new descriptor size (*size = ret).  Its
only userspace-visible effect is therefore the report descriptor size,
so checking the return value would amount to checking that size, which
means perturbing it.

Since the callback returns int and hid_bpf_get_data() returns a pointer,
the only way to return the helper result is to convert it, e.g.

	return !hid_bpf_get_data(hid_ctx, 2, ~0ULL);

On a fixed kernel the helper returns NULL, so this returns 1 and the
dispatch path truncates the report descriptor to 1 byte mid-test.  The
BSS variable records that the helper rejected the overflowing range
while the callback still returns 0 and leaves the descriptor untouched.

This matches the existing convention in progs/hid.c: callback_check and
callback2_check are BPF-side globals the userspace tests assert on, and
the existing hid_rdesc_fixup callback returns a positive size only when
it actually rewrites the descriptor (sizeof(rdesc) + 73).  The overflow
probe does not rewrite anything, so it returns 0 and reports the
helper's rejection through the BSS variable.

Thanks,
Yiyang


^ permalink raw reply

* Re: [PATCH v2 8/8] iio: accel: hid-sensor-accel-3d: Avoid race between callback setup and device exposure
From: sashiko-bot @ 2026-06-22  6:03 UTC (permalink / raw)
  To: Sanjay Chitroda; +Cc: dmitry.torokhov, linux-input
In-Reply-To: <20260622-5-june-hid-iio-race-fixes-v2-8-1cfabcd1881e@gmail.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

Pre-existing issues:
- [Critical] Pre-existing Use-After-Free during driver removal or probe failure due to lack of callback synchronization.
- [High] Pre-existing race condition between data push and buffer disable leading to infinite loop.
- [High] Missing length validation on `raw_data` in `accel_3d_capture_sample` leads to out-of-bounds reads and potential Information Leak.
--

commit d6d7cec4acad5d2e20a4e415413ae49c117fe317
Author: Sanjay Chitroda <sanjayembeddedse@gmail.com>

iio: accel: hid-sensor-accel-3d: Avoid race between callback setup and device exposure

This patch reorders the probe and remove paths in the hid-sensor-accel-3d
driver to ensure callbacks are registered before device exposure and removed
after the device is unregistered. This aims to prevent race conditions where
userspace might enable buffers before callbacks are fully set up.

> diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c
> index 42c4259bf2094..12481cfe9800a 100644
> --- a/drivers/iio/accel/hid-sensor-accel-3d.c
> +++ b/drivers/iio/accel/hid-sensor-accel-3d.c
> @@ -386,12 +386,6 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
>  		return ret;
>  	}
>  
> -	ret = iio_device_register(indio_dev);
> -	if (ret) {
> -		dev_err(&pdev->dev, "device register failed\n");
> -		goto error_remove_trigger;
> -	}
> -
>  	accel_state->callbacks.send_event = accel_3d_proc_event;
>  	accel_state->callbacks.capture_sample = accel_3d_capture_sample;

[Severity: High]
This isn't a bug introduced by this patch, but does this callback setup leave
us vulnerable to an out-of-bounds read?

Looking at accel_3d_capture_sample(), it casts the incoming raw_data pointer
without checking if raw_len is sufficiently large:

accel_3d_capture_sample()
    accel_state->scan.accel_val[CHANNEL_SCAN_INDEX_X + offset] =
        *(u32 *)raw_data;

Since raw_len is derived directly from the HID report descriptor provided by
the device, could a malicious device declare an artificially small field
(e.g., 1 byte) causing us to read adjacent kernel slab memory when
dereferencing as a u32 or int64_t?

>  	accel_state->callbacks.pdev = pdev;
> @@ -399,13 +393,19 @@ static int hid_accel_3d_probe(struct platform_device *pdev)

[ ... ]

> @@ -418,8 +418,8 @@ static void hid_accel_3d_remove(struct platform_device *pdev)
>  	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>  	struct accel_3d_state *accel_state = iio_priv(indio_dev);
>  
> -	sensor_hub_remove_callback(hsdev, hsdev->usage);
>  	iio_device_unregister(indio_dev);

[Severity: High]
This isn't a bug introduced by this patch, but could this unregister sequence
trigger an infinite loop during a concurrent data push?

If accel_3d_proc_event() is executing asynchronously in the HID event
context and observes data_ready > 0, it prepares to call
iio_push_to_buffers().

If preempted, another thread could execute this remove path:

hid_accel_3d_remove()
  -> iio_device_unregister()
    -> iio_disable_all_buffers()
      -> iio_buffer_deactivate_all()
        -> iio_buffer_deactivate()

iio_buffer_deactivate() uses list_del_init(&buffer->buffer_list), which makes
the list node self-referential. When iio_push_to_buffers() resumes its
lockless list_for_each_entry() traversal, will it infinite loop on this node?

> +	sensor_hub_remove_callback(hsdev, hsdev->usage);

[Severity: Critical]
This is a pre-existing issue, but does this callback removal leave a window
for a use-after-free?

sensor_hub_remove_callback() removes the callback from the list under a
spinlock but does not appear to wait for concurrently executing
sensor_hub_raw_event() handlers to complete.

Once hid_accel_3d_remove() returns, the devres framework will immediately
free indio_dev and accel_state. If a concurrent sensor_hub_raw_event() already
fetched the callback pointer:

sensor_hub_raw_event()
    if (callback->capture_sample) {
        if (report->field[i]->logical)
            callback->capture_sample(hsdev, ...);

Could it dereference the freed accel_state to execute capture_sample and
send_event, resulting in a use-after-free?

>  	hid_sensor_remove_trigger(indio_dev, &accel_state->common_attributes);
>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260622-5-june-hid-iio-race-fixes-v2-0-1cfabcd1881e@gmail.com?part=8

^ permalink raw reply

* Re: [PATCH v9 1/9] dt-bindings: mfd: mt6397: Add MT6392 PMIC
From: Krzysztof Kozlowski @ 2026-06-22  6:52 UTC (permalink / raw)
  To: Luca Leonardo Scorcia
  Cc: linux-mediatek, Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sen Chu, Sean Wang, Macpaul Lin, Lee Jones,
	Matthias Brugger, AngeloGioacchino Del Regno, Liam Girdwood,
	Mark Brown, Linus Walleij, Val Packett, Louis-Alexis Eyraud,
	Julien Massot, Fabien Parent, Akari Tsuyukusa, Chen Zhong,
	linux-input, devicetree, linux-kernel, linux-pm, linux-arm-kernel,
	linux-gpio
In-Reply-To: <20260621081634.467858-2-l.scorcia@gmail.com>

On Sun, Jun 21, 2026 at 10:13:26AM +0200, Luca Leonardo Scorcia wrote:
>                - enum:
>                    - mediatek,mt6359-rtc
> @@ -99,6 +107,7 @@ properties:
>                - mediatek,mt6331-regulator
>                - mediatek,mt6358-regulator
>                - mediatek,mt6359-regulator
> +              - mediatek,mt6392-regulator
>                - mediatek,mt6397-regulator
>            - items:
>                - enum:
> @@ -663,3 +672,69 @@ examples:
>              compatible = "mediatek,mt6397-rtc";
>          };
>      };
> +
> +  - |
> +    #include <dt-bindings/input/input.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +    pmic {
> +        compatible = "mediatek,mt6392", "mediatek,mt6323";

You already have three examples, that's rather close to max expected
number of them. I suggest dropping.

Anyway,

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>

Best regards,
Krzysztof


^ permalink raw reply

* [PATCH bpf-next v3 0/3] HID: bpf: Fix hid_bpf_get_data() range check
From: Yiyang Chen @ 2026-06-22  6:52 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, bpf, linux-input
  Cc: Yiyang Chen, Shuah Khan, Alexei Starovoitov, Daniel Borkmann,
	Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman,
	Kumar Kartikeya Dwivedi, Song Liu, Yonghong Song, Jiri Olsa,
	linux-kselftest, linux-kernel
In-Reply-To: <cover.1781964949.git.chenyy23@mails.tsinghua.edu.cn>

hid_bpf_get_data() exposes a pointer into the HID-BPF context data when
the caller-provided offset and size fit inside ctx->allocated_size.
The helper currently checks that range with:

  rdwr_buf_size + offset > ctx->allocated_size

Since both operands are unsigned, a very large size can wrap the sum and
make an out-of-range request look valid.

Patch 1 changes the helper to reject offset values beyond the allocation
and then compare the requested size against the remaining bytes.

Patch 2 updates the HID selftest loader to create only the struct_ops
maps requested by the current test, so unrelated programs from the shared
HID-BPF skeleton are not autoloaded.

Patch 3 adds a HID-BPF regression check that asks hid_bpf_get_data() for
offset 2 and size ~0ULL from an rdesc_fixup callback and expects NULL.
It also adds KHDR_INCLUDES to the HID selftest build so the userspace
test sees current kernel UAPI HID definitions.

Changes in v3:
  - Split out a HID selftest loader fix that disables autocreate for
    unrelated struct_ops maps.
  - Add a Fixes tag to the selftest patch.
  - Keep the BSS result flag in the rdesc fixup callback and explain why
    the callback must still return 0.

Changes in v2:
  - Drop the temporary data variable around the overflow
    hid_bpf_get_data() call in the selftest callback.
  - Correct the Fixes tag to commit 658ee5a64fcf ("HID: bpf: allocate
    data memory for device_event BPF programs").

v2: https://lore.kernel.org/bpf/cover.1781964949.git.chenyy23@mails.tsinghua.edu.cn/
v1: https://lore.kernel.org/bpf/cover.1781627122.git.chenyy23@mails.tsinghua.edu.cn/

Yiyang Chen (3):
  HID: bpf: Fix hid_bpf_get_data() range check
  selftests/hid: Load only requested struct_ops maps
  selftests/hid: Cover hid_bpf_get_data() size overflow

 drivers/hid/bpf/hid_bpf_dispatch.c      |  3 ++-
 tools/testing/selftests/hid/Makefile    |  2 +-
 tools/testing/selftests/hid/hid_bpf.c   | 36 ++++++++++++++++++++-----
 tools/testing/selftests/hid/progs/hid.c | 15 +++++++++++
 4 files changed, 47 insertions(+), 9 deletions(-)


base-commit: a975094bf98ca97be9146f9d3b5681a6f9cf5ce3
-- 
2.34.1


^ permalink raw reply

* Re: [PATCH v9 3/9] regulator: dt-bindings: Add MediaTek MT6392 PMIC
From: Krzysztof Kozlowski @ 2026-06-22  7:23 UTC (permalink / raw)
  To: Luca Leonardo Scorcia
  Cc: linux-mediatek, Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sen Chu, Sean Wang, Macpaul Lin, Lee Jones,
	Matthias Brugger, AngeloGioacchino Del Regno, Liam Girdwood,
	Mark Brown, Linus Walleij, Julien Massot, Louis-Alexis Eyraud,
	Val Packett, Fabien Parent, Akari Tsuyukusa, Chen Zhong,
	linux-input, devicetree, linux-kernel, linux-pm, linux-arm-kernel,
	linux-gpio
In-Reply-To: <20260621081634.467858-4-l.scorcia@gmail.com>

On Sun, Jun 21, 2026 at 10:13:28AM +0200, Luca Leonardo Scorcia wrote:
> Add bindings for the regulators found in the MediaTek MT6392 PMIC,
> usually found in board designs using the MediaTek MT8516/MT8167 SoCs.
> 
> Signed-off-by: Luca Leonardo Scorcia <l.scorcia@gmail.com>
> ---
>  .../regulator/mediatek,mt6392-regulator.yaml  | 112 ++++++++++++++++++
>  .../regulator/mediatek,mt6392-regulator.h     |  23 ++++
>  2 files changed, 135 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/regulator/mediatek,mt6392-regulator.yaml
>  create mode 100644 include/dt-bindings/regulator/mediatek,mt6392-regulator.h

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>

Best regards,
Krzysztof


^ permalink raw reply

* [PATCH bpf-next v3 1/3] HID: bpf: Fix hid_bpf_get_data() range check
From: Yiyang Chen @ 2026-06-22  7:30 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, bpf, linux-input
  Cc: Yiyang Chen, Shuah Khan, Alexei Starovoitov, Daniel Borkmann,
	Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman,
	Kumar Kartikeya Dwivedi, Song Liu, Yonghong Song, Jiri Olsa,
	linux-kselftest, linux-kernel
In-Reply-To: <20260622065246.414380-1-chenyy23@mails.tsinghua.edu.cn>

hid_bpf_get_data() returns a pointer into the HID-BPF context data when
the caller-provided offset and size fit inside ctx->allocated_size.

The current check adds rdwr_buf_size and offset before comparing the
result against ctx->allocated_size. Since both values are unsigned, a
very large size can wrap the sum below ctx->allocated_size and make the
helper return a pointer even though the requested range is not contained
in the backing buffer.

Use a non-wrapping range check instead: reject offsets beyond the
allocation, then compare the requested size with the remaining bytes
after the offset.

Fixes: 658ee5a64fcf ("HID: bpf: allocate data memory for device_event BPF programs")
Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
---
 drivers/hid/bpf/hid_bpf_dispatch.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c
index d0130658091b0..09b45c40d84f0 100644
--- a/drivers/hid/bpf/hid_bpf_dispatch.c
+++ b/drivers/hid/bpf/hid_bpf_dispatch.c
@@ -299,7 +299,8 @@ hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t rdwr
 
 	ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx);
 
-	if (rdwr_buf_size + offset > ctx->allocated_size)
+	if (offset > ctx->allocated_size ||
+	    rdwr_buf_size > ctx->allocated_size - offset)
 		return NULL;
 
 	return ctx_kern->data + offset;
-- 
2.34.1


^ permalink raw reply related

* [PATCH bpf-next v3 2/3] selftests/hid: Load only requested struct_ops maps
From: Yiyang Chen @ 2026-06-22  7:30 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, bpf, linux-input
  Cc: Yiyang Chen, Shuah Khan, Alexei Starovoitov, Daniel Borkmann,
	Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman,
	Kumar Kartikeya Dwivedi, Song Liu, Yonghong Song, Jiri Olsa,
	linux-kselftest, linux-kernel
In-Reply-To: <20260622073011.423657-1-chenyy23@mails.tsinghua.edu.cn>

The HID selftest skeleton contains several struct_ops maps, but each test
usually wants to load only the programs named by that test.

load_programs() disabled auto-attach for all maps, but left struct_ops
autocreate enabled. libbpf can enable autoload for programs referenced by
autocreated struct_ops maps, so an unrelated program can be loaded and fail
even when the current test does not use it.

Disable autocreate for all struct_ops maps by default, then re-enable it
only for the maps selected by the test before loading the skeleton.

Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
---
 tools/testing/selftests/hid/hid_bpf.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/tools/testing/selftests/hid/hid_bpf.c b/tools/testing/selftests/hid/hid_bpf.c
index 1e979fb3542ba..269256e1decd8 100644
--- a/tools/testing/selftests/hid/hid_bpf.c
+++ b/tools/testing/selftests/hid/hid_bpf.c
@@ -86,6 +86,20 @@ static void load_programs(const struct test_program programs[],
 	self->skel = hid__open();
 	ASSERT_OK_PTR(self->skel) TEARDOWN_LOG("Error while calling hid__open");
 
+	/*
+	 * Disable all struct_ops maps by default so libbpf does not autoload
+	 * programs referenced by maps that are unrelated to the current test.
+	 */
+	bpf_object__for_each_map(iter_map, *self->skel->skeleton->obj) {
+		if (bpf_map__type(iter_map) == BPF_MAP_TYPE_STRUCT_OPS) {
+			err = bpf_map__set_autocreate(iter_map, false);
+			ASSERT_OK(err) TH_LOG("can not disable struct_ops map '%s'",
+					      bpf_map__name(iter_map));
+		}
+
+		bpf_map__set_autoattach(iter_map, false);
+	}
+
 	for (int i = 0; i < progs_count; i++) {
 		struct bpf_program *prog;
 		struct bpf_map *map;
@@ -102,6 +116,10 @@ static void load_programs(const struct test_program programs[],
 		ASSERT_OK_PTR(map) TH_LOG("can not find struct_ops by name '%s'",
 					  programs[i].name + 4);
 
+		err = bpf_map__set_autocreate(map, true);
+		ASSERT_OK(err) TH_LOG("can not enable struct_ops map '%s'",
+				      programs[i].name + 4);
+
 		/* hid_id is the first field of struct hid_bpf_ops */
 		ops_hid_id = bpf_map__initial_value(map, NULL);
 		ASSERT_OK_PTR(ops_hid_id) TH_LOG("unable to retrieve struct_ops data");
@@ -109,13 +127,6 @@ static void load_programs(const struct test_program programs[],
 		*ops_hid_id = self->hid.hid_id;
 	}
 
-	/* we disable the auto-attach feature of all maps because we
-	 * only want the tested one to be manually attached in the next
-	 * call to bpf_map__attach_struct_ops()
-	 */
-	bpf_object__for_each_map(iter_map, *self->skel->skeleton->obj)
-		bpf_map__set_autoattach(iter_map, false);
-
 	err = hid__load(self->skel);
 	ASSERT_OK(err) TH_LOG("hid_skel_load failed: %d", err);
 
-- 
2.34.1


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox