]> git.ipfire.org Git - thirdparty/kernel/stable.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)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 1 Aug 2025 08:51:26 +0000 (09:51 +0100)
commit a7982a14b3012527a9583d12525cd0dc9f8d8934 upstream.

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
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/i2c/busses/i2c-qup.c

index 3a36d682ed5726d7a956180ea2072dc46d2f37d6..5b053e51f4c98ff5b1512a6fe4c361e579d340f2 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);
        }