From: bugzilla-daemon@kernel.org
To: linux-iio@vger.kernel.org
Subject: [Bug 221077] [iio] [hid-sensor-rotation] Memory corruption due to alignment mismatch in scan buffer
Date: Sat, 14 Feb 2026 20:29:26 +0000 [thread overview]
Message-ID: <bug-221077-217253-PAP7pA6Gyy@https.bugzilla.kernel.org/> (raw)
In-Reply-To: <bug-221077-217253@https.bugzilla.kernel.org/>
https://bugzilla.kernel.org/show_bug.cgi?id=221077
--- Comment #2 from dlechner@baylibre.com ---
On 2/14/26 1:24 PM, Jonathan Cameron wrote:
> On Wed, 11 Feb 2026 05:12:36 +0000
> bugzilla-daemon@kernel.org wrote:
>
>> https://bugzilla.kernel.org/show_bug.cgi?id=221077
>>
>> Bug ID: 221077
>> Summary: [iio] [hid-sensor-rotation] Memory corruption due to
>> alignment mismatch in scan buffer
>> Product: Drivers
>> Version: 2.5
>> Hardware: All
>> OS: Linux
>> Status: NEW
>> Severity: normal
>> Priority: P3
>> Component: IIO
>> Assignee: drivers_iio@kernel-bugs.kernel.org
>> Reporter: lixu.zhang@intel.com
>> Regression: Yes
>> Bisected b31a74075cb4ca2bb202a2e17d133ef3c9ee891f
>> commit-id:
>>
>> ### Problem
>> In `drivers/iio/orientation/hid-sensor-rotation.c`, the `scale_pre_decml`
>> and
>> `scale_post_decml` fields in `struct dev_rot_state` get corrupted after the
>> first read from the device. This issue results in invalid scale values being
>> reported to userspace.
>>
>> ### Root Cause Analysis
>> The issue is caused by a size mismatch between what the IIO core expects for
>> the scan buffer and the actual size of the driver's scan structure.
>>
>> 1. **Driver Structure**: The `scan` struct in `dev_rot_state` consists of a
>> quaternion (4 * s32 = 16 bytes) and a timestamp (8 bytes).
>> ```c
>> struct {
>> s32 sampled_vals[4];
>> aligned_s64 timestamp;
>> } scan;
>> ```
>> Without explicit alignment, this structure is packed to **24 bytes**.
>
> I agree it's 24 bytes, but worth being clear it has explicit alignment to 8
> bytes. Without that on some platforms it would be 4 byte aligned only.
>
>>
>> 2. **IIO Core Expectation**: The `iio_compute_scan_bytes` function
>> calculates
>> the buffer size required. It aligns the total size to the size of the
>> *largest
>> element* in the scan.
>> - The quaternion channel is treated as a single 16-byte element.
>> - Therefore, the core aligns the total size to 16 bytes: `ALIGN(24, 16)
>> =
>> 32 bytes`.
>
> Ah. That is indeed a corner case and the ABI is IIRC not well documented
> around that, let alone what we do in the kernel. We probably need to tighten
> that
> up as well as fixing this. What userspace were you using to test this?
I didn't even know we had IIO_MOD_QUATERNION as a special data type until
Francesco's recent patches. :-o
>
>
>>
>> 3. **Corruption**: When `iio_push_to_buffers_with_timestamp()` is called:
>> - It assumes a 32-byte buffer.
>> - It writes the timestamp at the end of the aligned buffer (offset 24).
>> - Since the driver allocated only 24 bytes for `scan`, the write at
>> offset
>> 24 overwrites the adjacent `scale_pre_decml` field in `struct
>> dev_rot_state`.
>>
>> ### Evidence (Ftrace)
>> I verified this by tracing the return values of `iio_storage_bytes_for_si`
>> and
>> `iio_compute_scan_bytes` using kretprobes:
>>
>> ```log
>> $ cat /sys/kernel/tracing/trace_pipe
>> r_store_bytes: (iio_compute_scan_bytes+0x30/0xd0 [industrialio] <-
>> iio_storage_bytes_for_si) arg1=0x10
>> r_store_bytes: (iio_compute_scan_bytes+0xa1/0xd0 [industrialio] <-
>> iio_storage_bytes_for_si) arg1=0x8
>> r_calc_bytes: (__iio_update_buffers+0x99d/0xd40 [industrialio] <-
>> iio_compute_scan_bytes) arg1=0x20
>> ```
>>
>> The trace confirms:
>> - Largest element = 16 bytes.
>> - Total raw size = 16 (quat) + 8 (ts) = 24 bytes.
>> - Final aligned size = ALIGN(24, 16) = 32 bytes.
>>
>> The memory layout mismatch is:
>> - IIO Core needs: 32 bytes
>> - Driver struct has: 24 bytes
>>
>> ### Regression
>> This issue was introduced by commit `b31a74075cb4 ("iio: orientation:
>> hid-sensor-rotation: remove unnecessary alignment")`, which removed the
>> `__aligned(16)` attribute that previously ensured the struct was padded to
>> 32
>> bytes.
>>
>> ### Proposed Fix
>> Revert the removal of `__aligned(16)` to ensure `struct dev_rot_state` has
>> the
>> correct padding to match the IIO core's expectations.
>>
>> ```c
>> struct {
>> s32 sampled_vals[4] __aligned(16);
> Agreed that fix is correct.
> However, we definitely also need to add some documentation on why it is
> there.
>
> It's not actually an alignment force on sampled_vals, but rather on the
> timestamp.
> We can't just mark the timestamp as then it will have two aligned markings on
> x86_32.
>
> David, given we both missed this when 'tidying' this up wrongly what do you
> think
> would make this clearest?
I think it would make sense to have an IIO_DECLARE_REPEAT_ELEMENT()
similar to IIO_DECLARE_BUFFER_WITH_TS().
#define IIO_DECLARE_REPEAT_ELEMENT(type, name, count) \
type name[count] __aligned(sizeof(type) * count)
And it would be used like:
struct {
IIO_DECLARE_REPEAT_ELEMENT(s32, sampled_vals, 4);
aligned_s64 timestamp;
} scan;
>
>
> Thanks for reporting this with such a thorough and detailed investigation!
> Makes our lives a lot easier.
Should I spin up a fix?
--
You may reply to this email to add a comment.
You are receiving this mail because:
You are watching the assignee of the bug.
next prev parent reply other threads:[~2026-02-14 20:29 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-11 5:12 [Bug 221077] New: [iio] [hid-sensor-rotation] Memory corruption due to alignment mismatch in scan buffer bugzilla-daemon
2026-02-14 19:24 ` Jonathan Cameron
2026-02-14 20:29 ` David Lechner
2026-02-15 16:23 ` Jonathan Cameron
2026-02-14 19:24 ` [Bug 221077] " bugzilla-daemon
2026-02-14 20:29 ` bugzilla-daemon [this message]
2026-02-15 16:23 ` bugzilla-daemon
2026-02-16 6:58 ` bugzilla-daemon
2026-02-16 7:03 ` bugzilla-daemon
2026-02-24 2:41 ` bugzilla-daemon
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=bug-221077-217253-PAP7pA6Gyy@https.bugzilla.kernel.org/ \
--to=bugzilla-daemon@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox