<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux.git/drivers/input, branch v7.2-rc1</title>
<subtitle>Linux kernel source tree</subtitle>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/'/>
<entry>
<title>Input: gscps2 - advance receive buffer write index</title>
<updated>2026-06-27T05:42:56+00:00</updated>
<author>
<name>Xu Rao</name>
<email>raoxu@uniontech.com</email>
</author>
<published>2026-06-24T09:47:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=d86d4f8cbb5a55a3b9b86f7b5ab8c4cdda600a3f'/>
<id>d86d4f8cbb5a55a3b9b86f7b5ab8c4cdda600a3f</id>
<content type='text'>
Commit 44f920069911 ("Input: gscps2 - use guard notation when
acquiring spinlock") moved the receive loop into gscps2_read_data()
and gscps2_report_data().

While moving the code, it preserved the writes to
buffer[ps2port-&gt;append], but omitted the following producer index
update from the original loop:

	ps2port-&gt;append = (ps2port-&gt;append + 1) &amp; BUFFER_SIZE;

As a result, append never advances. Since gscps2_report_data() only
reports bytes while act != append, the receive buffer always appears
empty and no keyboard or mouse data reaches the serio core.

Restore the omitted index update.

Fixes: 44f920069911 ("Input: gscps2 - use guard notation when acquiring spinlock")
Cc: stable@vger.kernel.org # 6.13+
Signed-off-by: Xu Rao &lt;raoxu@uniontech.com&gt;
Link: https://patch.msgid.link/460B5655BA580C60+20260624094739.850306-1-raoxu@uniontech.com
Signed-off-by: Dmitry Torokhov &lt;dmitry.torokhov@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Commit 44f920069911 ("Input: gscps2 - use guard notation when
acquiring spinlock") moved the receive loop into gscps2_read_data()
and gscps2_report_data().

While moving the code, it preserved the writes to
buffer[ps2port-&gt;append], but omitted the following producer index
update from the original loop:

	ps2port-&gt;append = (ps2port-&gt;append + 1) &amp; BUFFER_SIZE;

As a result, append never advances. Since gscps2_report_data() only
reports bytes while act != append, the receive buffer always appears
empty and no keyboard or mouse data reaches the serio core.

Restore the omitted index update.

Fixes: 44f920069911 ("Input: gscps2 - use guard notation when acquiring spinlock")
Cc: stable@vger.kernel.org # 6.13+
Signed-off-by: Xu Rao &lt;raoxu@uniontech.com&gt;
Link: https://patch.msgid.link/460B5655BA580C60+20260624094739.850306-1-raoxu@uniontech.com
Signed-off-by: Dmitry Torokhov &lt;dmitry.torokhov@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Input: rmi4 - tolerate short register descriptor structure</title>
<updated>2026-06-27T05:23:40+00:00</updated>
<author>
<name>Dmitry Torokhov</name>
<email>dmitry.torokhov@gmail.com</email>
</author>
<published>2026-06-26T23:33:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=2d6d33e45dd4fb768758d5f6e747deadcd66b9fc'/>
<id>2d6d33e45dd4fb768758d5f6e747deadcd66b9fc</id>
<content type='text'>
Some touchpads (e.g. ThinkPad T14 Gen 1) have buggy firmware that reports
a register descriptor structure size that is too small for the number of
registers it claims to have in the presence map. The remaining bytes in
the structure are 0, which with the new strict bounds checking causes the
parser to fail with -EIO, aborting the device probe.

Tolerate such short reads by dropping the remaining (unparseable or
0-size) registers from the list instead of failing the probe,
preventing the driver from trying to use them.

Fixes: 0adb483fbf2d ("Input: rmi4 - refactor register descriptor parsing")
Reported-by: Barry K. Nathan &lt;barryn@pobox.com&gt;
Tested-by: Barry K. Nathan &lt;barryn@pobox.com&gt;
Cc: stable@vger.kernel.org
Assisted-by: Antigravity:gemini-3.5-flash
Signed-off-by: Dmitry Torokhov &lt;dmitry.torokhov@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Some touchpads (e.g. ThinkPad T14 Gen 1) have buggy firmware that reports
a register descriptor structure size that is too small for the number of
registers it claims to have in the presence map. The remaining bytes in
the structure are 0, which with the new strict bounds checking causes the
parser to fail with -EIO, aborting the device probe.

Tolerate such short reads by dropping the remaining (unparseable or
0-size) registers from the list instead of failing the probe,
preventing the driver from trying to use them.

Fixes: 0adb483fbf2d ("Input: rmi4 - refactor register descriptor parsing")
Reported-by: Barry K. Nathan &lt;barryn@pobox.com&gt;
Tested-by: Barry K. Nathan &lt;barryn@pobox.com&gt;
Cc: stable@vger.kernel.org
Assisted-by: Antigravity:gemini-3.5-flash
Signed-off-by: Dmitry Torokhov &lt;dmitry.torokhov@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Revert "Input: rmi4 - fix register descriptor address calculation"</title>
<updated>2026-06-27T05:22:42+00:00</updated>
<author>
<name>Dmitry Torokhov</name>
<email>dmitry.torokhov@gmail.com</email>
</author>
<published>2026-06-27T00:42:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=d85589879f19ad8514c508709865f064be761df5'/>
<id>d85589879f19ad8514c508709865f064be761df5</id>
<content type='text'>
The register descriptor presence register is a packet register, which
means its bytes share a single RMI address. It does not occupy
consecutive addresses, and the register structure that follows it
is located at the next RMI address (presence_address + 1), not
(presence_address + presence_size).

Revert the incorrect address calculation introduced in commit
a98518e72439.

Reported-by: "Barry K. Nathan" &lt;barryn@pobox.com&gt;
Tested-by: "Barry K. Nathan" &lt;barryn@pobox.com&gt;
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov &lt;dmitry.torokhov@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The register descriptor presence register is a packet register, which
means its bytes share a single RMI address. It does not occupy
consecutive addresses, and the register structure that follows it
is located at the next RMI address (presence_address + 1), not
(presence_address + presence_size).

Revert the incorrect address calculation introduced in commit
a98518e72439.

Reported-by: "Barry K. Nathan" &lt;barryn@pobox.com&gt;
Tested-by: "Barry K. Nathan" &lt;barryn@pobox.com&gt;
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov &lt;dmitry.torokhov@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Input: synaptics-rmi4 - bound the F30 keymap to the GPIO/LED count</title>
<updated>2026-06-26T00:46:20+00:00</updated>
<author>
<name>Bryam Vargas</name>
<email>hexlabsecurity@proton.me</email>
</author>
<published>2026-06-14T05:36:12+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=d577e46785d45484b2ab7e7309c49b18764bf56c'/>
<id>d577e46785d45484b2ab7e7309c49b18764bf56c</id>
<content type='text'>
rmi_f30_map_gpios() allocates gpioled_key_map with
min(gpioled_count, TRACKSTICK_RANGE_END) == at most 6 entries, but
rmi_f30_attention() iterates the full f30-&gt;gpioled_count (device query
register, range 0..31) and dereferences gpioled_key_map[i], and
input-&gt;keycodemax is set to the full gpioled_count while input-&gt;keycode
points at the 6-entry allocation.

A device that reports gpioled_count &gt; 6 with GPIO support enabled
therefore causes an out-of-bounds read on the attention interrupt and
out-of-bounds read/write through the EVIOCGKEYCODE/EVIOCSKEYCODE ioctls,
which bound the index only against keycodemax. This is the same defect
as the F3A handler, which was copied from F30.

Size the keymap for the full gpioled_count; the mapping loop still
assigns only the first min(gpioled_count, TRACKSTICK_RANGE_END) entries.

Fixes: 3e64fcbdbd10 ("Input: synaptics-rmi4 - limit the range of what GPIOs are buttons")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas &lt;hexlabsecurity@proton.me&gt;
Link: https://patch.msgid.link/20260614-b4-disp-818d6bda-v1-2-cf39a3615085@proton.me
Signed-off-by: Dmitry Torokhov &lt;dmitry.torokhov@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
rmi_f30_map_gpios() allocates gpioled_key_map with
min(gpioled_count, TRACKSTICK_RANGE_END) == at most 6 entries, but
rmi_f30_attention() iterates the full f30-&gt;gpioled_count (device query
register, range 0..31) and dereferences gpioled_key_map[i], and
input-&gt;keycodemax is set to the full gpioled_count while input-&gt;keycode
points at the 6-entry allocation.

A device that reports gpioled_count &gt; 6 with GPIO support enabled
therefore causes an out-of-bounds read on the attention interrupt and
out-of-bounds read/write through the EVIOCGKEYCODE/EVIOCSKEYCODE ioctls,
which bound the index only against keycodemax. This is the same defect
as the F3A handler, which was copied from F30.

Size the keymap for the full gpioled_count; the mapping loop still
assigns only the first min(gpioled_count, TRACKSTICK_RANGE_END) entries.

Fixes: 3e64fcbdbd10 ("Input: synaptics-rmi4 - limit the range of what GPIOs are buttons")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas &lt;hexlabsecurity@proton.me&gt;
Link: https://patch.msgid.link/20260614-b4-disp-818d6bda-v1-2-cf39a3615085@proton.me
Signed-off-by: Dmitry Torokhov &lt;dmitry.torokhov@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Input: synaptics-rmi4 - bound the F3A keymap to the GPIO count</title>
<updated>2026-06-26T00:46:20+00:00</updated>
<author>
<name>Bryam Vargas</name>
<email>hexlabsecurity@proton.me</email>
</author>
<published>2026-06-14T05:36:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=57c10915f2c16c90e0d46ad00876bf39ece40fc2'/>
<id>57c10915f2c16c90e0d46ad00876bf39ece40fc2</id>
<content type='text'>
rmi_f3a_initialize() takes the GPIO count from the device query register
(f3a-&gt;gpio_count = buf &amp; RMI_F3A_GPIO_COUNT, range 0..127).
rmi_f3a_map_gpios() then allocates gpio_key_map with
min(gpio_count, TRACKSTICK_RANGE_END) == at most 6 entries, but
rmi_f3a_attention() iterates the full gpio_count and dereferences
gpio_key_map[i], and input-&gt;keycodemax is set to the full gpio_count
while input-&gt;keycode points at the 6-entry allocation.

A device that reports gpio_count &gt; 6 therefore causes an out-of-bounds
read of gpio_key_map[] on every attention interrupt, and out-of-bounds
accesses through the input core's default keymap ioctls: EVIOCGKEYCODE
reads past the buffer (leaking adjacent slab memory to user space) and
EVIOCSKEYCODE writes a caller-controlled value past it, for any process
able to open the evdev node, since input_default_getkeycode() and
input_default_setkeycode() only bound the index against keycodemax.

Size the keymap for the full gpio_count. The mapping loop is unchanged:
it still assigns only the first min(gpio_count, TRACKSTICK_RANGE_END)
entries; the remaining slots stay KEY_RESERVED (devm_kcalloc zero-fills)
and are skipped when reporting.

Fixes: 9e4c596bfd00 ("Input: synaptics-rmi4 - add support for F3A")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas &lt;hexlabsecurity@proton.me&gt;
Link: https://patch.msgid.link/20260614-b4-disp-818d6bda-v1-1-cf39a3615085@proton.me
Signed-off-by: Dmitry Torokhov &lt;dmitry.torokhov@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
rmi_f3a_initialize() takes the GPIO count from the device query register
(f3a-&gt;gpio_count = buf &amp; RMI_F3A_GPIO_COUNT, range 0..127).
rmi_f3a_map_gpios() then allocates gpio_key_map with
min(gpio_count, TRACKSTICK_RANGE_END) == at most 6 entries, but
rmi_f3a_attention() iterates the full gpio_count and dereferences
gpio_key_map[i], and input-&gt;keycodemax is set to the full gpio_count
while input-&gt;keycode points at the 6-entry allocation.

A device that reports gpio_count &gt; 6 therefore causes an out-of-bounds
read of gpio_key_map[] on every attention interrupt, and out-of-bounds
accesses through the input core's default keymap ioctls: EVIOCGKEYCODE
reads past the buffer (leaking adjacent slab memory to user space) and
EVIOCSKEYCODE writes a caller-controlled value past it, for any process
able to open the evdev node, since input_default_getkeycode() and
input_default_setkeycode() only bound the index against keycodemax.

Size the keymap for the full gpio_count. The mapping loop is unchanged:
it still assigns only the first min(gpio_count, TRACKSTICK_RANGE_END)
entries; the remaining slots stay KEY_RESERVED (devm_kcalloc zero-fills)
and are skipped when reporting.

Fixes: 9e4c596bfd00 ("Input: synaptics-rmi4 - add support for F3A")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas &lt;hexlabsecurity@proton.me&gt;
Link: https://patch.msgid.link/20260614-b4-disp-818d6bda-v1-1-cf39a3615085@proton.me
Signed-off-by: Dmitry Torokhov &lt;dmitry.torokhov@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 'next' into for-linus</title>
<updated>2026-06-23T06:10:08+00:00</updated>
<author>
<name>Dmitry Torokhov</name>
<email>dmitry.torokhov@gmail.com</email>
</author>
<published>2026-06-23T06:10:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=7a0e692a0381254b2f77c54dec100cd3325a6fdf'/>
<id>7a0e692a0381254b2f77c54dec100cd3325a6fdf</id>
<content type='text'>
Prepare input updates for 7.2 merge window.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Prepare input updates for 7.2 merge window.
</pre>
</div>
</content>
</entry>
<entry>
<title>Input: mms114 - fix touch indexing for MMS134S and MMS136</title>
<updated>2026-06-23T06:04:19+00:00</updated>
<author>
<name>Dmitry Torokhov</name>
<email>dmitry.torokhov@gmail.com</email>
</author>
<published>2026-06-23T05:35:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=a6ac4e24c1a8a533bb61035184fdcc7eede4cc8d'/>
<id>a6ac4e24c1a8a533bb61035184fdcc7eede4cc8d</id>
<content type='text'>
The MMS134S and MMS136 touch controllers have an event size of 6 bytes
rather than 8 bytes. When __mms114_read_reg() reads the touch data
packet from the device into the touch buffer, the events are packed
tightly at 6-byte intervals. However, the driver iterates through the
events using standard C array indexing (touch[index]), where each
element is sizeof(struct mms114_touch) (8 bytes) apart. As a result, any
touch events beyond the first one are read from incorrect offsets and
parsed improperly.

Fix this by explicitly calculating the byte offset for each touch event
based on the device's specific event size.

Fixes: 53fefdd1d3a3 ("Input: mms114 - support MMS136")
Fixes: ab108678195f ("Input: mms114 - support MMS134S")
Reported-by: sashiko-bot@kernel.org
Assisted-by: Antigravity:gemini-3.5-flash
Reviewed-by: Bryam Vargas &lt;hexlabsecurity@proton.me&gt;
Link: https://patch.msgid.link/20260616050912.1531241-1-dmitry.torokhov@gmail.com
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov &lt;dmitry.torokhov@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The MMS134S and MMS136 touch controllers have an event size of 6 bytes
rather than 8 bytes. When __mms114_read_reg() reads the touch data
packet from the device into the touch buffer, the events are packed
tightly at 6-byte intervals. However, the driver iterates through the
events using standard C array indexing (touch[index]), where each
element is sizeof(struct mms114_touch) (8 bytes) apart. As a result, any
touch events beyond the first one are read from incorrect offsets and
parsed improperly.

Fix this by explicitly calculating the byte offset for each touch event
based on the device's specific event size.

Fixes: 53fefdd1d3a3 ("Input: mms114 - support MMS136")
Fixes: ab108678195f ("Input: mms114 - support MMS134S")
Reported-by: sashiko-bot@kernel.org
Assisted-by: Antigravity:gemini-3.5-flash
Reviewed-by: Bryam Vargas &lt;hexlabsecurity@proton.me&gt;
Link: https://patch.msgid.link/20260616050912.1531241-1-dmitry.torokhov@gmail.com
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov &lt;dmitry.torokhov@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Input: elan_i2c - prevent division by zero and arithmetic underflow</title>
<updated>2026-06-23T05:33:02+00:00</updated>
<author>
<name>Ranjan Kumar</name>
<email>kumarranja@chromium.org</email>
</author>
<published>2026-06-23T05:31:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=df2b818fa009c10ff6ba875a1663ff001cda9558'/>
<id>df2b818fa009c10ff6ba875a1663ff001cda9558</id>
<content type='text'>
The Elan I2C touchpad driver queries the device for its physical
dimensions and trace counts to calculate the device resolution and width.
However, if the device firmware or device tree provides invalid zero
values for x_traces or y_traces, it results in a fatal division-by-zero
exception leading to a kernel panic during device probe.

Add checks to ensure these parameters are non-zero before performing
the division. If invalid trace values are detected, fall back to a safe
default of 1.

Additionally, prevent an arithmetic underflow in the touch reporting
logic. Previously, if the calculated or fallback width was smaller than
ETP_FWIDTH_REDUCE (90), the subtraction would underflow, resulting in a
massive unsigned integer being reported to userspace. Clamp the adjusted
width to a minimum of 0 to safely handle small physical dimensions and
fallback scenarios.

Completing the probe with safe fallback values ensures the sysfs nodes
are created, keeping the firmware update path intact so a recovery
firmware can be flashed to the device.

Fixes: 6696777c6506 ("Input: add driver for Elan I2C/SMbus touchpad")
Fixes: e3a9a1290688 ("Input: elan_i2c - do not query the info if they are provided")
Signed-off-by: Ranjan Kumar &lt;kumarranja@chromium.org&gt;
Link: https://patch.msgid.link/20260612060339.3829666-1-kumarranja@chromium.org
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov &lt;dmitry.torokhov@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The Elan I2C touchpad driver queries the device for its physical
dimensions and trace counts to calculate the device resolution and width.
However, if the device firmware or device tree provides invalid zero
values for x_traces or y_traces, it results in a fatal division-by-zero
exception leading to a kernel panic during device probe.

Add checks to ensure these parameters are non-zero before performing
the division. If invalid trace values are detected, fall back to a safe
default of 1.

Additionally, prevent an arithmetic underflow in the touch reporting
logic. Previously, if the calculated or fallback width was smaller than
ETP_FWIDTH_REDUCE (90), the subtraction would underflow, resulting in a
massive unsigned integer being reported to userspace. Clamp the adjusted
width to a minimum of 0 to safely handle small physical dimensions and
fallback scenarios.

Completing the probe with safe fallback values ensures the sysfs nodes
are created, keeping the firmware update path intact so a recovery
firmware can be flashed to the device.

Fixes: 6696777c6506 ("Input: add driver for Elan I2C/SMbus touchpad")
Fixes: e3a9a1290688 ("Input: elan_i2c - do not query the info if they are provided")
Signed-off-by: Ranjan Kumar &lt;kumarranja@chromium.org&gt;
Link: https://patch.msgid.link/20260612060339.3829666-1-kumarranja@chromium.org
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov &lt;dmitry.torokhov@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Input: stop force-feedback timer when unregistering input devices</title>
<updated>2026-06-23T05:33:01+00:00</updated>
<author>
<name>Dmitry Torokhov</name>
<email>dmitry.torokhov@gmail.com</email>
</author>
<published>2026-06-06T22:04:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=ef166ce08801c5237662868d9ec0331d53a38ece'/>
<id>ef166ce08801c5237662868d9ec0331d53a38ece</id>
<content type='text'>
Memoryless force-feedback devices use a timer to manage playback of
effects. When a driver for such a device is unbound (or the device is
unregistered for other reasons), the driver typically frees its private
data synchronously. However, the input_dev structure (and its associated
force-feedback structures, including the timer) is only freed when the
last user closes the corresponding device node.

If userspace keeps the device node open while the device is unregistered
(e.g., during driver unbind), the force-feedback timer can still fire
after the driver's private data has been freed.

Introduce a new 'stop' callback to struct ff_device, and call it from
input_unregister_device() before the device is deleted. Implement this
callback for memoryless devices and synchronously shut down the timer to
ensure it is stopped and cannot be rearmed once unregistration happens.

Assisted-by: Gemini:gemini-3.1-pro
Signed-off-by: Dmitry Torokhov &lt;dmitry.torokhov@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Memoryless force-feedback devices use a timer to manage playback of
effects. When a driver for such a device is unbound (or the device is
unregistered for other reasons), the driver typically frees its private
data synchronously. However, the input_dev structure (and its associated
force-feedback structures, including the timer) is only freed when the
last user closes the corresponding device node.

If userspace keeps the device node open while the device is unregistered
(e.g., during driver unbind), the force-feedback timer can still fire
after the driver's private data has been freed.

Introduce a new 'stop' callback to struct ff_device, and call it from
input_unregister_device() before the device is deleted. Implement this
callback for memoryless devices and synchronously shut down the timer to
ensure it is stopped and cannot be rearmed once unregistration happens.

Assisted-by: Gemini:gemini-3.1-pro
Signed-off-by: Dmitry Torokhov &lt;dmitry.torokhov@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Input: iforce - bound the device-reported force-feedback effect index</title>
<updated>2026-06-23T03:55:41+00:00</updated>
<author>
<name>Bryam Vargas</name>
<email>hexlabsecurity@proton.me</email>
</author>
<published>2026-06-23T03:47:50+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=0e9943d2e4c63496b6ca84bc66fd3c71d40558e2'/>
<id>0e9943d2e4c63496b6ca84bc66fd3c71d40558e2</id>
<content type='text'>
iforce_process_packet() handles a status report (packet id 0x02) by
taking a force-feedback effect index straight from the device wire and
using it to address the per-effect state array:

	i = data[1] &amp; 0x7f;
	if (data[1] &amp; 0x80) {
		if (!test_and_set_bit(FF_CORE_IS_PLAYED,
				      iforce-&gt;core_effects[i].flags))
			...
	} else if (test_and_clear_bit(FF_CORE_IS_PLAYED,
				      iforce-&gt;core_effects[i].flags)) {
		...
	}

The index is masked only with 0x7f, so it ranges 0..127, but
core_effects[] holds only IFORCE_EFFECTS_MAX (32) entries.  For an index
of 32..127 the test_and_set_bit()/test_and_clear_bit() is an
out-of-bounds single-bit read-modify-write past the array.  core_effects[]
is the second-to-last member of struct iforce, so the write lands in the
trailing members and beyond the embedding kzalloc()'d iforce_serio /
iforce_usb object.

data[1] is unvalidated device payload on both transports (the USB
interrupt endpoint and serio), and the status path is not gated on force
feedback being present, so a malicious or counterfeit device can set or
clear a bit at an attacker-chosen offset past the object.

Reject an out-of-range index instead of indexing with it.  Bound against
the array dimension IFORCE_EFFECTS_MAX rather than dev-&gt;ff-&gt;max_effects so
the check guarantees memory safety regardless of how many effects the
device registered.  A legitimate "effect started/stopped" status always
carries an index below IFORCE_EFFECTS_MAX, so well-formed devices are
unaffected; the neighbouring mark_core_as_ready() loop is already bounded
and is left untouched.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bryam Vargas &lt;hexlabsecurity@proton.me&gt;
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260613-b4-disp-4828d263-v1-1-02320e1a89dd@proton.me
Signed-off-by: Dmitry Torokhov &lt;dmitry.torokhov@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
iforce_process_packet() handles a status report (packet id 0x02) by
taking a force-feedback effect index straight from the device wire and
using it to address the per-effect state array:

	i = data[1] &amp; 0x7f;
	if (data[1] &amp; 0x80) {
		if (!test_and_set_bit(FF_CORE_IS_PLAYED,
				      iforce-&gt;core_effects[i].flags))
			...
	} else if (test_and_clear_bit(FF_CORE_IS_PLAYED,
				      iforce-&gt;core_effects[i].flags)) {
		...
	}

The index is masked only with 0x7f, so it ranges 0..127, but
core_effects[] holds only IFORCE_EFFECTS_MAX (32) entries.  For an index
of 32..127 the test_and_set_bit()/test_and_clear_bit() is an
out-of-bounds single-bit read-modify-write past the array.  core_effects[]
is the second-to-last member of struct iforce, so the write lands in the
trailing members and beyond the embedding kzalloc()'d iforce_serio /
iforce_usb object.

data[1] is unvalidated device payload on both transports (the USB
interrupt endpoint and serio), and the status path is not gated on force
feedback being present, so a malicious or counterfeit device can set or
clear a bit at an attacker-chosen offset past the object.

Reject an out-of-range index instead of indexing with it.  Bound against
the array dimension IFORCE_EFFECTS_MAX rather than dev-&gt;ff-&gt;max_effects so
the check guarantees memory safety regardless of how many effects the
device registered.  A legitimate "effect started/stopped" status always
carries an index below IFORCE_EFFECTS_MAX, so well-formed devices are
unaffected; the neighbouring mark_core_as_ready() loop is already bounded
and is left untouched.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bryam Vargas &lt;hexlabsecurity@proton.me&gt;
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260613-b4-disp-4828d263-v1-1-02320e1a89dd@proton.me
Signed-off-by: Dmitry Torokhov &lt;dmitry.torokhov@gmail.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
