From: Joshua Crofts <joshua.crofts1@gmail.com>
To: "กิตติศักดิ์ บุญมาปะ" <goorock.goopop@gmail.com>
Cc: linux-iio@vger.kernel.org, jic23@kernel.org
Subject: Re: [BUG] hid-sensor-trigger: poll_value sign unchecked before msleep_interruptible causes ~49.7 day sleep
Date: Wed, 1 Jul 2026 09:28:24 +0200 [thread overview]
Message-ID: <20260701092824.000040e4@gmail.com> (raw)
In-Reply-To: <CAPr6G1qLDrgHvCNsVxj7xHxYUKkAkyo87Hq3Lfyoj3RaZ2v4dg@mail.gmail.com>
On Wed, 1 Jul 2026 09:40:54 +0700
กิตติศักดิ์ บุญมาปะ <goorock.goopop@gmail.com> wrote:
> KERNEL BUG REPORT
> =================
> Component : drivers/iio/common/hid-sensors/hid-sensor-trigger.c
> Subsystem : IIO / HID Sensor
> Severity : High (device permanently unusable until service restart)
> Kernel : confirmed on 6.17.x; code path present in mainline as of 2025-06
>
> Summary
> -------
> _hid_sensor_power_state() passes the return value of
> hid_sensor_read_poll_value() directly to msleep_interruptible()
> without checking for a negative (error) return. When the HID
> descriptor does not contain a Report Interval feature field the
> function returns -EINVAL (-22). This value is implicitly converted
> to unsigned int before being multiplied by 2 and passed to
> msleep_interruptible(), producing a sleep duration of
> ~4,294,967,252 ms (~49.7 days). The process enters
> TASK_INTERRUPTIBLE state and appears permanently hung to the user.
>
>
> Affected Code
> -------------
> drivers/iio/common/hid-sensors/hid-sensor-trigger.c:
>
> static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state)
> {
> ...
> s32 poll_value = 0;
> ...
> poll_value = hid_sensor_read_poll_value(st); // can return -EINVAL
> ...
> if (state && poll_value) // BUG: -22
> passes this check
> msleep_interruptible(poll_value * 2); // -22 * 2 cast
> to uint = ~4.29e9 ms
> ...
> }
>
> hid_sensor_read_poll_value() (hid-sensor-attributes.c):
>
> s32 hid_sensor_read_poll_value(struct hid_sensor_common *st)
> {
> s32 value = 0;
> int ret;
>
> ret = sensor_hub_get_feature(st->hsdev,
> st->poll.report_id, // 0xffffffff
> if not found
> st->poll.index, sizeof(value), &value);
>
> if (ret < 0 || value < 0) {
> return -EINVAL; // returned when Report Interval not in descriptor
> }
> ...
> return value;
> }
>
>
> Reproduction
> ------------
> Hardware : Seeed XIAO nRF52840 Sense (LSM6DS3 IMU) via USB HID
> VID:PID 2886:8045
> OS : Bazzite (Fedora immutable), kernel 6.17.x
> Drivers : hid-sensor-hub, hid-sensor-accel-3d, iio-sensor-proxy
>
> The device implements a USB HID Sensor (Usage Page 0x20,
> Accelerometer 3D, usage 0x200073) with Power State (0x200319),
> Report State (0x200316) feature fields — sufficient for probe to
> succeed — but without Report Interval (0x20030E).
>
> Steps:
> 1. Plug the device.
> 2. Allow iio-sensor-proxy to start and attempt the first read.
> 3. Observe: iio-sensor-proxy main thread enters D/S state and
> never returns. 'cat in_accel_x_raw' also hangs indefinitely.
> 4. systemctl restart iio-sensor-proxy unblocks all hung processes
> (SIGTERM interrupts the interruptible sleep).
>
> Kernel stack trace (captured via /proc/<pid>/task/*/stack while
> process was hung — iio-sensor-proxy PID 1011, kernel 6.17.x):
>
> [<0>] msleep_interruptible+0x3b/0x90
> [<0>] _hid_sensor_power_state+0x166/0x1e0 [hid_sensor_trigger]
> [<0>] __rpm_callback+0x48/0x1f0
> [<0>] rpm_callback+0x6d/0x80
> [<0>] rpm_resume+0x4af/0x6d0
> [<0>] __pm_runtime_resume+0x52/0x90
> [<0>] hid_sensor_power_state+0x51/0xe0 [hid_sensor_trigger]
> [<0>] accel_3d_read_raw+0xa8/0x210 [hid_sensor_accel_3d]
> [<0>] iio_read_channel_info+0xed/0x110 [industrialio]
> [<0>] dev_attr_show+0x1f/0x50
> [<0>] sysfs_kf_seq_show+0xcc/0x120
> [<0>] seq_read_iter+0x128/0x480
> [<0>] vfs_read+0x268/0x390
> [<0>] ksys_read+0x73/0xf0
> [<0>] do_syscall_64+0x7e/0x250
> [<0>] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>
> Note: the process is in TASK_INTERRUPTIBLE (wchan=msleep_interruptible,
> STAT=S), not TASK_UNINTERRUPTIBLE — it responds to signals. This is
> why a service restart (SIGTERM) unblocks it, and why it is easy to
> mistake for a runtime PM deadlock rather than an unchecked sleep duration.
>
>
> Proposed Fix
> ------------
> drivers/iio/common/hid-sensors/hid-sensor-trigger.c:
>
> --- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
> +++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
> @@ -143,7 +143,7 @@ static int _hid_sensor_power_state(...)
> poll_value = hid_sensor_read_poll_value(st);
> }
> - if (state && poll_value)
> + if (state && poll_value > 0)
> msleep_interruptible(poll_value * 2);
>
Yes, this is something that should be fixed. Can you send a patch?
--
Kind regards
CJD
next prev parent reply other threads:[~2026-07-01 7:28 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-01 2:40 [BUG] hid-sensor-trigger: poll_value sign unchecked before msleep_interruptible causes ~49.7 day sleep กิตติศักดิ์ บุญมาปะ
2026-07-01 7:28 ` Joshua Crofts [this message]
2026-07-01 17:43 ` Jonathan Cameron
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260701092824.000040e4@gmail.com \
--to=joshua.crofts1@gmail.com \
--cc=goorock.goopop@gmail.com \
--cc=jic23@kernel.org \
--cc=linux-iio@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.