linux/drivers/i2c
Mingyu Wang 10dd1a736d
i2c: i801: fix hardware state machine corruption in error path
A severe livelock and subsequent Hung Task panic were observed in the
i2c-i801 driver during concurrent Fuzzing. The crash is caused by an
unconditional hardware register cleanup in the error handling path of
i801_access().

When i801_check_pre() fails (e.g., returning -EBUSY because the SMBus
controller is actively used by BIOS/ACPI), the kernel does not actually
acquire the hardware ownership. However, the code jumps to the 'out'
label and executes:

    iowrite8(SMBHSTSTS_INUSE_STS | STATUS_FLAGS, SMBHSTSTS(priv));

This forcefully clears the INUSE_STS lock and resets the hardware status
flags without owning the controller. Doing so interrupts ongoing BIOS/ACPI
transactions and totally corrupts the SMBus hardware state machine.

Consequently, all subsequent i801_access() calls fail at the pre-check
stage, triggering an endless stream of "SMBus is busy, can't use it!"
error logs. Over a slow serial console, this printk flood monopolizes
the CPU (Console Livelock), starving other processes trying to acquire
the mmap_lock down_read semaphore, ultimately triggering the hung task
watchdog.

Fix this by moving the 'out' label below the hardware register cleanup.
If i801_check_pre() fails, we safely bypass the iowrite8() and only
release the software locks (pm_runtime and mutex), strictly adhering to
the rule of not releasing resources that were never acquired.

Fixes: 1f760b87e5 ("i2c: i801: Call i801_check_pre() from i801_access()")
Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn>
Cc: <stable@vger.kernel.org> # v6.3+
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://lore.kernel.org/r/20260512093534.348655-1-w15303746062@163.com
2026-06-23 17:53:08 +02:00
..
algos i2c: algo: bit: use str_plural helper in bit_xfer 2026-06-16 23:58:35 +02:00
busses i2c: i801: fix hardware state machine corruption in error path 2026-06-23 17:53:08 +02:00
muxes i2c: mux: reg: use device property accessors 2026-06-09 13:00:33 +02:00
i2c-atr.c i2c: atr: use kzalloc_flex 2026-04-10 01:16:59 +02:00
i2c-boardinfo.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
i2c-core-acpi.c i2c for v7.2 2026-06-16 07:43:29 +05:30
i2c-core-base.c i2c for v7.2 2026-06-16 07:43:29 +05:30
i2c-core-of-prober.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
i2c-core-of.c Revert "treewide: Fix probing of devices in DT overlays" 2026-05-22 13:33:58 +02:00
i2c-core-slave.c i2c: Use trace_call__##name() at guarded tracepoint call sites 2026-03-26 10:24:39 -04:00
i2c-core-smbus.c i2c: smbus: fix a potential uninitialization bug 2026-05-19 12:43:08 +02:00
i2c-core.h i2c: Unexport i2c_of_match_device() 2025-02-13 16:47:52 +01:00
i2c-dev.c i2c: dev: prevent integer overflow in I2C_TIMEOUT ioctl 2026-05-04 11:31:35 +02:00
i2c-mux.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
i2c-slave-eeprom.c i2c: Use named initializers for arrays of i2c_device_data 2026-06-05 01:09:25 +02:00
i2c-slave-testunit.c i2c for v7.2 2026-06-16 07:43:29 +05:30
i2c-smbus.c i2c: Use named initializers for arrays of i2c_device_data 2026-06-05 01:09:25 +02:00
i2c-stub.c i2c: stub: Reject I2C block transfers with invalid length 2026-05-04 13:23:53 +02:00
Kconfig
Makefile i2c: Introduce OF component probe function 2024-11-27 12:04:10 +01:00