Blob Blame History Raw
From: Qinglang Miao <miaoqinglang@huawei.com>
Date: Tue, 1 Dec 2020 17:31:17 +0800
Subject: i2c: cadence: fix reference leak when pm_runtime_get_sync fails
Git-commit: 23ceb8462dc6f4b4decdb5536a7e5fc477cdf0b6
Patch-mainline: v5.13
References: bsc#1220570 CVE-2020-36784

The PM reference count is not expected to be incremented on
return in functions cdns_i2c_master_xfer and cdns_reg_slave.

However, pm_runtime_get_sync will increment pm usage counter
even failed. Forgetting to putting operation will result in a
reference leak here.

Replace it with pm_runtime_resume_and_get to keep usage
counter balanced.

[JD: backporting notes:
 Only fix cdns_i2c_master_xfer as cdns_reg_slave did not exist
 in this version of the kernel.
 Also, we can't use pm_runtime_resume_and_get which did not exist
 yet, so manually call pm_runtime_put_noidle on failure instead.]

Fixes: 7fa32329ca03 ("i2c: cadence: Move to sensible power management")
Reported-by: Hulk Robot <hulkci@huawei.com>
Signed-off-by: Qinglang Miao <miaoqinglang@huawei.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
Acked-by: Jean Delvare <jdelvare@suse.de>
---
 drivers/i2c/busses/i2c-cadence.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

--- a/drivers/i2c/busses/i2c-cadence.c
+++ b/drivers/i2c/busses/i2c-cadence.c
@@ -579,8 +579,10 @@ static int cdns_i2c_master_xfer(struct i
 	bool hold_quirk;
 
 	ret = pm_runtime_get_sync(id->dev);
-	if (ret < 0)
+	if (ret < 0) {
+		pm_runtime_put_noidle(id->dev);
 		return ret;
+	}
 	/* Check if the bus is free */
 	if (cdns_i2c_readreg(CDNS_I2C_SR_OFFSET) & CDNS_I2C_SR_BA) {
 		ret = -EAGAIN;