<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux.git/drivers/i2c, branch v7.1-rc5</title>
<subtitle>Linux kernel source tree</subtitle>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/'/>
<entry>
<title>i2c: smbus: fix a potential uninitialization bug</title>
<updated>2026-05-19T10:43:08+00:00</updated>
<author>
<name>Wenwen Wang</name>
<email>wang6495@umn.edu</email>
</author>
<published>2018-05-05T12:57:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=023453cb7eb0f53c5dc36babed8e706c1b0b0187'/>
<id>023453cb7eb0f53c5dc36babed8e706c1b0b0187</id>
<content type='text'>
In i2c_smbus_xfer_emulated(), there are two buffers: msgbuf0 and
msgbuf1, which are used to save a series of messages, as mentioned in
the comment. According to the value of the variable 'size', msgbuf0 is
initialized to various values. In contrast, msgbuf1 is left
uninitialized until the function i2c_transfer() is invoked. However,
msgbuf1 is not always initialized on all possible execution paths
(implementation) of i2c_transfer(). Thus, it is possible that msgbuf1
may still be uninitialized even after the invocation of the function
i2c_transfer(), especially when the return value of i2c_transfer() is
not checked properly. In the following execution, the uninitialized
msgbuf1 will be used, such as for security checks. Since uninitialized
values can be random and arbitrary, this will cause undefined behaviors
or even check bypass. For example, it is expected that if the value of
'size' is I2C_SMBUS_BLOCK_PROC_CALL, the value of data-&gt;block[0] should
not be larger than I2C_SMBUS_BLOCK_MAX. This patch initializes the first
byte of msgbuf1 with 0 to avoid such undefined behaviors or security
issues.

Signed-off-by: Wenwen Wang &lt;wang6495@umn.edu&gt;
[wsa: reworded commit message a little]
Signed-off-by: Wolfram Sang &lt;wsa+renesas@sang-engineering.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
In i2c_smbus_xfer_emulated(), there are two buffers: msgbuf0 and
msgbuf1, which are used to save a series of messages, as mentioned in
the comment. According to the value of the variable 'size', msgbuf0 is
initialized to various values. In contrast, msgbuf1 is left
uninitialized until the function i2c_transfer() is invoked. However,
msgbuf1 is not always initialized on all possible execution paths
(implementation) of i2c_transfer(). Thus, it is possible that msgbuf1
may still be uninitialized even after the invocation of the function
i2c_transfer(), especially when the return value of i2c_transfer() is
not checked properly. In the following execution, the uninitialized
msgbuf1 will be used, such as for security checks. Since uninitialized
values can be random and arbitrary, this will cause undefined behaviors
or even check bypass. For example, it is expected that if the value of
'size' is I2C_SMBUS_BLOCK_PROC_CALL, the value of data-&gt;block[0] should
not be larger than I2C_SMBUS_BLOCK_MAX. This patch initializes the first
byte of msgbuf1 with 0 to avoid such undefined behaviors or security
issues.

Signed-off-by: Wenwen Wang &lt;wang6495@umn.edu&gt;
[wsa: reworded commit message a little]
Signed-off-by: Wolfram Sang &lt;wsa+renesas@sang-engineering.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>i2c: tegra: make tegra_i2c_mutex_unlock() return void</title>
<updated>2026-05-13T22:14:20+00:00</updated>
<author>
<name>Saurav Sachidanand</name>
<email>sauravsc@amazon.com</email>
</author>
<published>2026-05-07T22:11:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=30792d12842901f5276f466a960962d5bfa15cc8'/>
<id>30792d12842901f5276f466a960962d5bfa15cc8</id>
<content type='text'>
tegra_i2c_mutex_unlock() returning an error that overwrites the transfer
result causes silent loss of I2C transfer errors. If the transfer failed
but the unlock succeeded, the error was lost and the function incorrectly
reported success.

Rather than propagating the unlock error (which is not actionable by the
caller - the I2C message may have been sent regardless), convert the
function to return void and WARN on the unexpected condition. If the
unlock fails, subsequent lock attempts will fail anyway, making the error
visible on the next transfer.

Fixes: 6077cfd716fb ("i2c: tegra: Add support for SW mutex register")
Signed-off-by: Saurav Sachidanand &lt;sauravsc@amazon.com&gt;
Cc: &lt;stable@vger.kernel.org&gt; # v7.0+
Reviewed-by: Jon Hunter &lt;jonathanh@nvidia.com&gt;
Acked-by: Thierry Reding &lt;treding@nvidia.com&gt;
Signed-off-by: Andi Shyti &lt;andi.shyti@kernel.org&gt;
Link: https://lore.kernel.org/r/20260507221145.62183-3-sauravsc@amazon.com
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
tegra_i2c_mutex_unlock() returning an error that overwrites the transfer
result causes silent loss of I2C transfer errors. If the transfer failed
but the unlock succeeded, the error was lost and the function incorrectly
reported success.

Rather than propagating the unlock error (which is not actionable by the
caller - the I2C message may have been sent regardless), convert the
function to return void and WARN on the unexpected condition. If the
unlock fails, subsequent lock attempts will fail anyway, making the error
visible on the next transfer.

Fixes: 6077cfd716fb ("i2c: tegra: Add support for SW mutex register")
Signed-off-by: Saurav Sachidanand &lt;sauravsc@amazon.com&gt;
Cc: &lt;stable@vger.kernel.org&gt; # v7.0+
Reviewed-by: Jon Hunter &lt;jonathanh@nvidia.com&gt;
Acked-by: Thierry Reding &lt;treding@nvidia.com&gt;
Signed-off-by: Andi Shyti &lt;andi.shyti@kernel.org&gt;
Link: https://lore.kernel.org/r/20260507221145.62183-3-sauravsc@amazon.com
</pre>
</div>
</content>
</entry>
<entry>
<title>i2c: tegra: fix pm_runtime leak on mutex_lock failure</title>
<updated>2026-05-13T22:14:06+00:00</updated>
<author>
<name>Saurav Sachidanand</name>
<email>sauravsc@amazon.com</email>
</author>
<published>2026-05-07T22:11:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=57cf4e8d6a57dc2ef5810f4852a23ba4c71b74bb'/>
<id>57cf4e8d6a57dc2ef5810f4852a23ba4c71b74bb</id>
<content type='text'>
If tegra_i2c_mutex_lock() fails, the function returns without calling
pm_runtime_put(), leaking the runtime PM reference acquired by the
preceding pm_runtime_get_sync(). This prevents the device from ever
entering runtime suspend.

Add the missing pm_runtime_put() before returning on lock failure.

Fixes: 6077cfd716fb ("i2c: tegra: Add support for SW mutex register")
Signed-off-by: Saurav Sachidanand &lt;sauravsc@amazon.com&gt;
Cc: &lt;stable@vger.kernel.org&gt; # v7.0+
Reviewed-by: Jon Hunter &lt;jonathanh@nvidia.com&gt;
Acked-by: Thierry Reding &lt;treding@nvidia.com&gt;
Signed-off-by: Andi Shyti &lt;andi.shyti@kernel.org&gt;
Link: https://lore.kernel.org/r/20260507221145.62183-2-sauravsc@amazon.com
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
If tegra_i2c_mutex_lock() fails, the function returns without calling
pm_runtime_put(), leaking the runtime PM reference acquired by the
preceding pm_runtime_get_sync(). This prevents the device from ever
entering runtime suspend.

Add the missing pm_runtime_put() before returning on lock failure.

Fixes: 6077cfd716fb ("i2c: tegra: Add support for SW mutex register")
Signed-off-by: Saurav Sachidanand &lt;sauravsc@amazon.com&gt;
Cc: &lt;stable@vger.kernel.org&gt; # v7.0+
Reviewed-by: Jon Hunter &lt;jonathanh@nvidia.com&gt;
Acked-by: Thierry Reding &lt;treding@nvidia.com&gt;
Signed-off-by: Andi Shyti &lt;andi.shyti@kernel.org&gt;
Link: https://lore.kernel.org/r/20260507221145.62183-2-sauravsc@amazon.com
</pre>
</div>
</content>
</entry>
<entry>
<title>i2c: smbus: reject oversized block transfers in the common path</title>
<updated>2026-05-07T08:59:07+00:00</updated>
<author>
<name>Weiming Shi</name>
<email>bestswngs@gmail.com</email>
</author>
<published>2026-05-05T17:55:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=3051cd060fa496df42954291fa2306ed2eab4ecc'/>
<id>3051cd060fa496df42954291fa2306ed2eab4ecc</id>
<content type='text'>
The SMBus block transfer length data-&gt;block[0] is validated in
i2c_smbus_xfer_emulated() but that check runs too late for tracepoints
and is skipped entirely when the adapter provides a native smbus_xfer
implementation. This allows user-controlled oversized block lengths to
reach tracepoint memcpy calls and driver callbacks unchecked.

Add an early validation in __i2c_smbus_xfer() that rejects block
transfers whose caller-supplied length is zero or exceeds
I2C_SMBUS_BLOCK_MAX before any tracepoint fires or driver callback
runs. data-&gt;block[0] is filled in by the device on SMBus block reads,
so the check is scoped to operations where the length is actually
supplied by the caller. This is consistent with the existing -EINVAL
convention in the emulated path and protects all downstream consumers
at once: the smbus_write tracepoint, all native smbus_xfer driver
implementations, and the emulated path.

Two distinct bugs are fixed by this change:

Bug 1: smbus_write tracepoint OOB (include/trace/events/smbus.h)
  trace_smbus_write() fires before any validation and copies
  data-&gt;block[0]+1 bytes into a 34-byte event buffer. With
  block[0]=0xfe the tracepoint copies 255 bytes, overflowing by 221.

 BUG: KASAN: stack-out-of-bounds in trace_event_raw_event_smbus_write+0x27c/0x530
 Read of size 255 at addr ffff88800d98fcf8 by task poc_smbus/91
 Call Trace:
  &lt;TASK&gt;
  __asan_memcpy+0x23/0x80
  trace_event_raw_event_smbus_write+0x27c/0x530
  __i2c_smbus_xfer+0x43a/0xa40
  i2c_smbus_xfer+0x19e/0x340
  i2cdev_ioctl_smbus+0x38f/0x7f0
  i2cdev_ioctl+0x35e/0x680
  __x64_sys_ioctl+0x147/0x1e0
  do_syscall_64+0xcf/0x15a0
  entry_SYSCALL_64_after_hwframe+0x76/0x7e
  &lt;/TASK&gt;

Bug 2: i2c-stub I2C_SMBUS_I2C_BLOCK_DATA OOB (drivers/i2c/i2c-stub.c)
  stub_xfer() implements .smbus_xfer directly and only clamps
  block[0] against 256-command, not I2C_SMBUS_BLOCK_MAX. With
  block[0]=0xff and command=0 the loop accesses block[1+i] for
  i up to 254, far past the 34-byte union.

 UBSAN: array-index-out-of-bounds in drivers/i2c/i2c-stub.c:223:44
 index 34 is out of range for type '__u8 [34]'
 Call Trace:
  &lt;TASK&gt;
  __ubsan_handle_out_of_bounds+0xd7/0x120
  stub_xfer+0x1971/0x198f [i2c_stub]
  __i2c_smbus_xfer+0x306/0xa40
  i2c_smbus_xfer+0x19e/0x340
  i2cdev_ioctl_smbus+0x38f/0x7f0
  i2cdev_ioctl+0x35e/0x680
  __x64_sys_ioctl+0x147/0x1e0
  do_syscall_64+0xcf/0x15a0
  entry_SYSCALL_64_after_hwframe+0x76/0x7e
  &lt;/TASK&gt;

Both traces reproduced on v7.0-rc6+i2c/for-current with KASAN+UBSAN.

Fixes: 8a325997d95d ("i2c: Add message transfer tracepoints for SMBUS [ver #2]")
Fixes: 4710317891e4 ("i2c-stub: Implement I2C block support")
Reported-by: Xiang Mei &lt;xmei5@asu.edu&gt;
Signed-off-by: Weiming Shi &lt;bestswngs@gmail.com&gt;
Signed-off-by: Wolfram Sang &lt;wsa+renesas@sang-engineering.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The SMBus block transfer length data-&gt;block[0] is validated in
i2c_smbus_xfer_emulated() but that check runs too late for tracepoints
and is skipped entirely when the adapter provides a native smbus_xfer
implementation. This allows user-controlled oversized block lengths to
reach tracepoint memcpy calls and driver callbacks unchecked.

Add an early validation in __i2c_smbus_xfer() that rejects block
transfers whose caller-supplied length is zero or exceeds
I2C_SMBUS_BLOCK_MAX before any tracepoint fires or driver callback
runs. data-&gt;block[0] is filled in by the device on SMBus block reads,
so the check is scoped to operations where the length is actually
supplied by the caller. This is consistent with the existing -EINVAL
convention in the emulated path and protects all downstream consumers
at once: the smbus_write tracepoint, all native smbus_xfer driver
implementations, and the emulated path.

Two distinct bugs are fixed by this change:

Bug 1: smbus_write tracepoint OOB (include/trace/events/smbus.h)
  trace_smbus_write() fires before any validation and copies
  data-&gt;block[0]+1 bytes into a 34-byte event buffer. With
  block[0]=0xfe the tracepoint copies 255 bytes, overflowing by 221.

 BUG: KASAN: stack-out-of-bounds in trace_event_raw_event_smbus_write+0x27c/0x530
 Read of size 255 at addr ffff88800d98fcf8 by task poc_smbus/91
 Call Trace:
  &lt;TASK&gt;
  __asan_memcpy+0x23/0x80
  trace_event_raw_event_smbus_write+0x27c/0x530
  __i2c_smbus_xfer+0x43a/0xa40
  i2c_smbus_xfer+0x19e/0x340
  i2cdev_ioctl_smbus+0x38f/0x7f0
  i2cdev_ioctl+0x35e/0x680
  __x64_sys_ioctl+0x147/0x1e0
  do_syscall_64+0xcf/0x15a0
  entry_SYSCALL_64_after_hwframe+0x76/0x7e
  &lt;/TASK&gt;

Bug 2: i2c-stub I2C_SMBUS_I2C_BLOCK_DATA OOB (drivers/i2c/i2c-stub.c)
  stub_xfer() implements .smbus_xfer directly and only clamps
  block[0] against 256-command, not I2C_SMBUS_BLOCK_MAX. With
  block[0]=0xff and command=0 the loop accesses block[1+i] for
  i up to 254, far past the 34-byte union.

 UBSAN: array-index-out-of-bounds in drivers/i2c/i2c-stub.c:223:44
 index 34 is out of range for type '__u8 [34]'
 Call Trace:
  &lt;TASK&gt;
  __ubsan_handle_out_of_bounds+0xd7/0x120
  stub_xfer+0x1971/0x198f [i2c_stub]
  __i2c_smbus_xfer+0x306/0xa40
  i2c_smbus_xfer+0x19e/0x340
  i2cdev_ioctl_smbus+0x38f/0x7f0
  i2cdev_ioctl+0x35e/0x680
  __x64_sys_ioctl+0x147/0x1e0
  do_syscall_64+0xcf/0x15a0
  entry_SYSCALL_64_after_hwframe+0x76/0x7e
  &lt;/TASK&gt;

Both traces reproduced on v7.0-rc6+i2c/for-current with KASAN+UBSAN.

Fixes: 8a325997d95d ("i2c: Add message transfer tracepoints for SMBUS [ver #2]")
Fixes: 4710317891e4 ("i2c-stub: Implement I2C block support")
Reported-by: Xiang Mei &lt;xmei5@asu.edu&gt;
Signed-off-by: Weiming Shi &lt;bestswngs@gmail.com&gt;
Signed-off-by: Wolfram Sang &lt;wsa+renesas@sang-engineering.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>i2c: stub: Reject I2C block transfers with invalid length</title>
<updated>2026-05-04T11:23:53+00:00</updated>
<author>
<name>Weiming Shi</name>
<email>bestswngs@gmail.com</email>
</author>
<published>2026-04-14T17:23:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=6036b5067a8199ba7a2dc7b377d4b9dd276d5f9e'/>
<id>6036b5067a8199ba7a2dc7b377d4b9dd276d5f9e</id>
<content type='text'>
The I2C_SMBUS_I2C_BLOCK_DATA case in stub_xfer() uses data-&gt;block[0]
as the transfer length. The existing check only clamps it to avoid
overrunning the chip-&gt;words[256] register array, but does not validate
it against I2C_SMBUS_BLOCK_MAX (32), which is the limit of the union
i2c_smbus_data.block buffer (34 bytes total). The driver is a
development/test tool (CONFIG_I2C_STUB=m, not built by default)
that must be loaded with a chip_addr= parameter.

A local user with access to /dev/i2c-* can issue an I2C_SMBUS ioctl
with I2C_SMBUS_I2C_BLOCK_DATA and data-&gt;block[0] &gt; 32, causing
stub_xfer() to read or write past the end of the union
i2c_smbus_data.block buffer:

 BUG: KASAN: stack-out-of-bounds in stub_xfer (drivers/i2c/i2c-stub.c:223)
 Read of size 1 at addr ffff88800abcfd92 by task exploit/81
 Call Trace:
  &lt;TASK&gt;
  stub_xfer (drivers/i2c/i2c-stub.c:223)
  __i2c_smbus_xfer (drivers/i2c/i2c-core-smbus.c:593)
  i2c_smbus_xfer (drivers/i2c/i2c-core-smbus.c:536)
  i2cdev_ioctl_smbus (drivers/i2c/i2c-dev.c:391)
  i2cdev_ioctl (drivers/i2c/i2c-dev.c:478)
  __x64_sys_ioctl (fs/ioctl.c:583)
  do_syscall_64 (arch/x86/entry/syscall_64.c:94)
  entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
  &lt;/TASK&gt;

The bug exists because i2c-stub implements .smbus_xfer directly,
bypassing the I2C_SMBUS_BLOCK_MAX validation in
i2c_smbus_xfer_emulated(). The I2C_SMBUS_BLOCK_DATA case in the same
function correctly validates against I2C_SMBUS_BLOCK_MAX, but the
I2C_SMBUS_I2C_BLOCK_DATA case does not.

Fix by rejecting transfers with data-&gt;block[0] == 0 or
data-&gt;block[0] &gt; I2C_SMBUS_BLOCK_MAX with -EINVAL, consistent with
both the I2C_SMBUS_BLOCK_DATA case in the same function and the
I2C_SMBUS_I2C_BLOCK_DATA validation in i2c_smbus_xfer_emulated().

Fixes: 4710317891e4 ("i2c-stub: Implement I2C block support")
Reported-by: Xiang Mei &lt;xmei5@asu.edu&gt;
Signed-off-by: Weiming Shi &lt;bestswngs@gmail.com&gt;
Reviewed-by: Jean Delvare &lt;jdelvare@suse.de&gt;
Signed-off-by: Wolfram Sang &lt;wsa+renesas@sang-engineering.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The I2C_SMBUS_I2C_BLOCK_DATA case in stub_xfer() uses data-&gt;block[0]
as the transfer length. The existing check only clamps it to avoid
overrunning the chip-&gt;words[256] register array, but does not validate
it against I2C_SMBUS_BLOCK_MAX (32), which is the limit of the union
i2c_smbus_data.block buffer (34 bytes total). The driver is a
development/test tool (CONFIG_I2C_STUB=m, not built by default)
that must be loaded with a chip_addr= parameter.

A local user with access to /dev/i2c-* can issue an I2C_SMBUS ioctl
with I2C_SMBUS_I2C_BLOCK_DATA and data-&gt;block[0] &gt; 32, causing
stub_xfer() to read or write past the end of the union
i2c_smbus_data.block buffer:

 BUG: KASAN: stack-out-of-bounds in stub_xfer (drivers/i2c/i2c-stub.c:223)
 Read of size 1 at addr ffff88800abcfd92 by task exploit/81
 Call Trace:
  &lt;TASK&gt;
  stub_xfer (drivers/i2c/i2c-stub.c:223)
  __i2c_smbus_xfer (drivers/i2c/i2c-core-smbus.c:593)
  i2c_smbus_xfer (drivers/i2c/i2c-core-smbus.c:536)
  i2cdev_ioctl_smbus (drivers/i2c/i2c-dev.c:391)
  i2cdev_ioctl (drivers/i2c/i2c-dev.c:478)
  __x64_sys_ioctl (fs/ioctl.c:583)
  do_syscall_64 (arch/x86/entry/syscall_64.c:94)
  entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
  &lt;/TASK&gt;

The bug exists because i2c-stub implements .smbus_xfer directly,
bypassing the I2C_SMBUS_BLOCK_MAX validation in
i2c_smbus_xfer_emulated(). The I2C_SMBUS_BLOCK_DATA case in the same
function correctly validates against I2C_SMBUS_BLOCK_MAX, but the
I2C_SMBUS_I2C_BLOCK_DATA case does not.

Fix by rejecting transfers with data-&gt;block[0] == 0 or
data-&gt;block[0] &gt; I2C_SMBUS_BLOCK_MAX with -EINVAL, consistent with
both the I2C_SMBUS_BLOCK_DATA case in the same function and the
I2C_SMBUS_I2C_BLOCK_DATA validation in i2c_smbus_xfer_emulated().

Fixes: 4710317891e4 ("i2c-stub: Implement I2C block support")
Reported-by: Xiang Mei &lt;xmei5@asu.edu&gt;
Signed-off-by: Weiming Shi &lt;bestswngs@gmail.com&gt;
Reviewed-by: Jean Delvare &lt;jdelvare@suse.de&gt;
Signed-off-by: Wolfram Sang &lt;wsa+renesas@sang-engineering.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>i2c: Compare the return value of gpiod_get_direction against GPIO_LINE_DIRECTION_OUT</title>
<updated>2026-05-04T10:19:25+00:00</updated>
<author>
<name>Nikola Z. Ivanov</name>
<email>zlatistiv@gmail.com</email>
</author>
<published>2026-04-15T20:50:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=b47bc7c022ddab7c79a84dd5f3f0d07fe09ec786'/>
<id>b47bc7c022ddab7c79a84dd5f3f0d07fe09ec786</id>
<content type='text'>
The GPIO_LINE_DIRECTION_* definitions have just recently been exposed to
gpio consumers.h by breaking them out in a separate defs.h file.

Use this to validate the gpio direction instead of the hard-coded literal.

Signed-off-by: Nikola Z. Ivanov &lt;zlatistiv@gmail.com&gt;
Signed-off-by: Wolfram Sang &lt;wsa+renesas@sang-engineering.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The GPIO_LINE_DIRECTION_* definitions have just recently been exposed to
gpio consumers.h by breaking them out in a separate defs.h file.

Use this to validate the gpio direction instead of the hard-coded literal.

Signed-off-by: Nikola Z. Ivanov &lt;zlatistiv@gmail.com&gt;
Signed-off-by: Wolfram Sang &lt;wsa+renesas@sang-engineering.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>i2c: dev: prevent integer overflow in I2C_TIMEOUT ioctl</title>
<updated>2026-05-04T09:31:35+00:00</updated>
<author>
<name>Mingyu Wang</name>
<email>25181214217@stu.xidian.edu.cn</email>
</author>
<published>2026-04-27T02:57:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=617eb7c0961a8dfcfc811844a6396e406b2923ea'/>
<id>617eb7c0961a8dfcfc811844a6396e406b2923ea</id>
<content type='text'>
While fuzzing with Syzkaller, a persistent `schedule_timeout: wrong
timeout value` warning was observed, accompanied by SMBus controller
state machine corruption.

The I2C_TIMEOUT ioctl accepts a user-provided timeout in multiples of
10 ms. The user argument is checked against INT_MAX, but it is
subsequently multiplied by 10 before being passed to msecs_to_jiffies().

A malicious user can pass a large value (e.g., 429496729) that passes
the `arg &gt; INT_MAX` check but overflows when multiplied by 10. This
results in a truncated 32-bit unsigned value that bypasses the
internal `(int)m &lt; 0` check in `msecs_to_jiffies()`.

The truncated value is then assigned to `client-&gt;adapter-&gt;timeout`
(a signed 32-bit int), which is reinterpreted as a negative number.
When passed to wait_for_completion_timeout(), this negative value
undergoes sign extension to a 64-bit unsigned long, triggering the
`schedule_timeout` warning and causing premature returns. This leaves
the SMBus state machine in an unrecoverable state, constituting a
local Denial of Service (DoS).

Fix this by bounding the user argument to `INT_MAX / 10`.

Signed-off-by: Mingyu Wang &lt;25181214217@stu.xidian.edu.cn&gt;
[wsa: move the comment as well]
Signed-off-by: Wolfram Sang &lt;wsa+renesas@sang-engineering.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
While fuzzing with Syzkaller, a persistent `schedule_timeout: wrong
timeout value` warning was observed, accompanied by SMBus controller
state machine corruption.

The I2C_TIMEOUT ioctl accepts a user-provided timeout in multiples of
10 ms. The user argument is checked against INT_MAX, but it is
subsequently multiplied by 10 before being passed to msecs_to_jiffies().

A malicious user can pass a large value (e.g., 429496729) that passes
the `arg &gt; INT_MAX` check but overflows when multiplied by 10. This
results in a truncated 32-bit unsigned value that bypasses the
internal `(int)m &lt; 0` check in `msecs_to_jiffies()`.

The truncated value is then assigned to `client-&gt;adapter-&gt;timeout`
(a signed 32-bit int), which is reinterpreted as a negative number.
When passed to wait_for_completion_timeout(), this negative value
undergoes sign extension to a 64-bit unsigned long, triggering the
`schedule_timeout` warning and causing premature returns. This leaves
the SMBus state machine in an unrecoverable state, constituting a
local Denial of Service (DoS).

Fix this by bounding the user argument to `INT_MAX / 10`.

Signed-off-by: Mingyu Wang &lt;25181214217@stu.xidian.edu.cn&gt;
[wsa: move the comment as well]
Signed-off-by: Wolfram Sang &lt;wsa+renesas@sang-engineering.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>i2c: acpi: Add ELAN0678 to i2c_acpi_force_100khz_device_ids</title>
<updated>2026-05-04T09:17:46+00:00</updated>
<author>
<name>Niels Franke</name>
<email>nielsfranke@gmail.com</email>
</author>
<published>2026-04-18T05:37:19+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=9998e388be9930c106eb5904c23ecf2162407527'/>
<id>9998e388be9930c106eb5904c23ecf2162407527</id>
<content type='text'>
The ELAN0678 touchpad (04F3:3195) found in the Lenovo ThinkPad X13
exhibits excessive smoothing when the I2C bus runs at 400KHz, making
the touchpad feel sluggish when plugged into AC power. This is the
same issue previously fixed for ELAN06FA.

The device's ACPI table (Lenovo TP-R22) specifies 0x00061A80 (400KHz)
for the I2cSerialBusV2 descriptor. Forcing the bus to 100KHz eliminates
the sluggish behavior.

Signed-off-by: Niels Franke &lt;nielsfranke@gmail.com&gt;
Acked-by: Mika Westerberg &lt;mika.westerberg@linux.intel.com&gt;
[wsa: kept the sorting]
Signed-off-by: Wolfram Sang &lt;wsa+renesas@sang-engineering.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The ELAN0678 touchpad (04F3:3195) found in the Lenovo ThinkPad X13
exhibits excessive smoothing when the I2C bus runs at 400KHz, making
the touchpad feel sluggish when plugged into AC power. This is the
same issue previously fixed for ELAN06FA.

The device's ACPI table (Lenovo TP-R22) specifies 0x00061A80 (400KHz)
for the I2cSerialBusV2 descriptor. Forcing the bus to 100KHz eliminates
the sluggish behavior.

Signed-off-by: Niels Franke &lt;nielsfranke@gmail.com&gt;
Acked-by: Mika Westerberg &lt;mika.westerberg@linux.intel.com&gt;
[wsa: kept the sorting]
Signed-off-by: Wolfram Sang &lt;wsa+renesas@sang-engineering.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>i2c: stm32f7: reinit_completion() per transfer not per msg</title>
<updated>2026-05-04T08:22:00+00:00</updated>
<author>
<name>Marek Vasut</name>
<email>marex@nabladev.com</email>
</author>
<published>2026-05-02T15:31:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=02b7cd683892d8d8464815d69a3a76579909a726'/>
<id>02b7cd683892d8d8464815d69a3a76579909a726</id>
<content type='text'>
Currently, the driver may repeatedly call reinit_completion() during
transfer which contains multiple messages, while another thread is
waiting for the completion.

This happens during transfer with more than 1 message, invoked via
stm32f7_i2c_xfer_core() -&gt; stm32f7_i2c_xfer_msg(). After invoking the
stm32f7_i2c_xfer_msg() to start transfer, stm32f7_i2c_xfer_core()
calls wait_for_completion_timeout() to wait for completion of the
transfer of all messages. When the first message transfer completes,
the hard IRQ handler triggers, and detects transfer completion, which
leads to stm32f7_i2c_isr_event_thread() IRQ thread being started. The
stm32f7_i2c_isr_event_thread() calls stm32f7_i2c_xfer_msg() in case
there are more messages.

Without this change, the second and later stm32f7_i2c_xfer_msg() would
call reinit_completion() on the completion which is still being waited
for in stm32f7_i2c_xfer_core(). Fix this by moving the reinit_completion()
into stm32f7_i2c_xfer_core(), together with wait_for_completion_timeout().

Since stm32f7_i2c_xfer_core() now waits for completion of the entire
transfer, increase the default timeout. This fixes sporadic transfer
timeouts on STM32MP25xx during kernel boot.

Fixes: aeb068c57214 ("i2c: i2c-stm32f7: add driver")
Signed-off-by: Marek Vasut &lt;marex@nabladev.com&gt;
[wsa: reworded commit subject]
Signed-off-by: Wolfram Sang &lt;wsa+renesas@sang-engineering.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Currently, the driver may repeatedly call reinit_completion() during
transfer which contains multiple messages, while another thread is
waiting for the completion.

This happens during transfer with more than 1 message, invoked via
stm32f7_i2c_xfer_core() -&gt; stm32f7_i2c_xfer_msg(). After invoking the
stm32f7_i2c_xfer_msg() to start transfer, stm32f7_i2c_xfer_core()
calls wait_for_completion_timeout() to wait for completion of the
transfer of all messages. When the first message transfer completes,
the hard IRQ handler triggers, and detects transfer completion, which
leads to stm32f7_i2c_isr_event_thread() IRQ thread being started. The
stm32f7_i2c_isr_event_thread() calls stm32f7_i2c_xfer_msg() in case
there are more messages.

Without this change, the second and later stm32f7_i2c_xfer_msg() would
call reinit_completion() on the completion which is still being waited
for in stm32f7_i2c_xfer_core(). Fix this by moving the reinit_completion()
into stm32f7_i2c_xfer_core(), together with wait_for_completion_timeout().

Since stm32f7_i2c_xfer_core() now waits for completion of the entire
transfer, increase the default timeout. This fixes sporadic transfer
timeouts on STM32MP25xx during kernel boot.

Fixes: aeb068c57214 ("i2c: i2c-stm32f7: add driver")
Signed-off-by: Marek Vasut &lt;marex@nabladev.com&gt;
[wsa: reworded commit subject]
Signed-off-by: Wolfram Sang &lt;wsa+renesas@sang-engineering.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>i2c: testunit: Replace system_long_wq with system_dfl_long_wq</title>
<updated>2026-05-04T08:07:46+00:00</updated>
<author>
<name>Marco Crivellari</name>
<email>marco.crivellari@suse.com</email>
</author>
<published>2026-04-30T09:08:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=8bc6b14aab669f0c301febcf4aa5249b9393bf51'/>
<id>8bc6b14aab669f0c301febcf4aa5249b9393bf51</id>
<content type='text'>
Currently the code enqueue work items using {queue|mod}_delayed_work(),
using system_long_wq. This workqueue should be used when long works are
expected, but it is a per-cpu workqueue.

This is important because queue_delayed_work() queue the work using:

   queue_delayed_work_on(WORK_CPU_UNBOUND, ...);

Note that WORK_CPU_UNBOUND = NR_CPUS.

This would end up calling __queue_delayed_work() that does:

    if (housekeeping_enabled(HK_TYPE_TIMER)) {
    //      [....]
    } else {
            if (likely(cpu == WORK_CPU_UNBOUND))
                    add_timer_global(timer);
            else
                    add_timer_on(timer, cpu);
    }

So when cpu == WORK_CPU_UNBOUND the timer is global and is
not using a specific CPU. Later, when __queue_work() is called:

    if (req_cpu == WORK_CPU_UNBOUND) {
            if (wq-&gt;flags &amp; WQ_UNBOUND)
                    cpu = wq_select_unbound_cpu(raw_smp_processor_id());
            else
                    cpu = raw_smp_processor_id();
    }

Because the wq is not unbound, it takes the CPU where the timer
fired and enqueue the work on that CPU.
The consequence of all of this is that the work can run anywhere,
depending on where the timer fired.

Recently, a new unbound workqueue specific for long running work has
been added:

    c116737e972e ("workqueue: Add system_dfl_long_wq for long unbound works")

So change system_long_wq with system_dfl_long_wq so that the work may
benefit from scheduler task placement.

Signed-off-by: Marco Crivellari &lt;marco.crivellari@suse.com&gt;
[wsa: remove FIXME as well]
Signed-off-by: Wolfram Sang &lt;wsa+renesas@sang-engineering.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Currently the code enqueue work items using {queue|mod}_delayed_work(),
using system_long_wq. This workqueue should be used when long works are
expected, but it is a per-cpu workqueue.

This is important because queue_delayed_work() queue the work using:

   queue_delayed_work_on(WORK_CPU_UNBOUND, ...);

Note that WORK_CPU_UNBOUND = NR_CPUS.

This would end up calling __queue_delayed_work() that does:

    if (housekeeping_enabled(HK_TYPE_TIMER)) {
    //      [....]
    } else {
            if (likely(cpu == WORK_CPU_UNBOUND))
                    add_timer_global(timer);
            else
                    add_timer_on(timer, cpu);
    }

So when cpu == WORK_CPU_UNBOUND the timer is global and is
not using a specific CPU. Later, when __queue_work() is called:

    if (req_cpu == WORK_CPU_UNBOUND) {
            if (wq-&gt;flags &amp; WQ_UNBOUND)
                    cpu = wq_select_unbound_cpu(raw_smp_processor_id());
            else
                    cpu = raw_smp_processor_id();
    }

Because the wq is not unbound, it takes the CPU where the timer
fired and enqueue the work on that CPU.
The consequence of all of this is that the work can run anywhere,
depending on where the timer fired.

Recently, a new unbound workqueue specific for long running work has
been added:

    c116737e972e ("workqueue: Add system_dfl_long_wq for long unbound works")

So change system_long_wq with system_dfl_long_wq so that the work may
benefit from scheduler task placement.

Signed-off-by: Marco Crivellari &lt;marco.crivellari@suse.com&gt;
[wsa: remove FIXME as well]
Signed-off-by: Wolfram Sang &lt;wsa+renesas@sang-engineering.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
