]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
i2c: qup: jump out of the loop in case of timeout
authorYang Xiwen <forbidden405@outlook.com>
Sun, 15 Jun 2025 16:01:10 +0000 (00:01 +0800)
committerAndi Shyti <andi.shyti@kernel.org>
Wed, 23 Jul 2025 22:38:01 +0000 (00:38 +0200)
Original logic only sets the return value but doesn't jump out of the
loop if the bus is kept active by a client. This is not expected. A
malicious or buggy i2c client can hang the kernel in this case and
should be avoided. This is observed during a long time test with a
PCA953x GPIO extender.

Fix it by changing the logic to not only sets the return value, but also
jumps out of the loop and return to the caller with -ETIMEDOUT.

Fixes: fbfab1ab0658 ("i2c: qup: reorganization of driver code to remove polling for qup v1")
Signed-off-by: Yang Xiwen <forbidden405@outlook.com>
Cc: <stable@vger.kernel.org> # v4.17+
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://lore.kernel.org/r/20250616-qca-i2c-v1-1-2a8d37ee0a30@outlook.com
drivers/i2c/busses/i2c-qup.c

index 6059f585843ebc4db9c2ea4dc3053b14541a59b8..fc348924d52254f70628f60acb104050b4845c3b 100644 (file)
@@ -452,8 +452,10 @@ static int qup_i2c_bus_active(struct qup_i2c_dev *qup, int len)
                if (!(status & I2C_STATUS_BUS_ACTIVE))
                        break;
 
-               if (time_after(jiffies, timeout))
+               if (time_after(jiffies, timeout)) {
                        ret = -ETIMEDOUT;
+                       break;
+               }
 
                usleep_range(len, len * 2);
        }