From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f50.google.com (mail-wm1-f50.google.com [209.85.128.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9042F2F6577 for ; Sun, 6 Sep 2026 22:37:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.50 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788734265; cv=none; b=P+oW17HhpqtawpsrG9rOuHUF2w2qraBTKubifJ/4EH+pMnzxKEjtE05i8wlBkULEA9avbb/y3ZtR43Ji0UEpfv3PiBD8LverUV0HzoJO0SS14rOAH/jO482bA2wLSqpE6ywZQmLy7PlstT2mdlpkfgG6BI3mk0Dj/oKw34gAeVY= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788734265; c=relaxed/simple; bh=1nyGnRR7H0bApTzHX7MBbxqgr1IQhdKxtm5fS0KuE9A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MazOra3tA2MKDqPpNnkslSuKkaGhZFFeP5Ku1ZY152+2EazXcF2nfB7BlO0DCsuBo/fyftWBnrUCQ8IDbJvyo+zyaKuQiZtH5ENakpgawHNXpCs1fszstiX6UbQJgcwKiSkGywewsFBmhIqfZctnn1TlWbnv7hUyhKEaF9mHzSE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=b6AL1OPi; arc=none smtp.client-ip=209.85.128.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="b6AL1OPi" Received: by mail-wm1-f50.google.com with SMTP id 5b1f17b1804b1-499b2981a7bso30442515e9.3 for ; Sun, 06 Sep 2026 15:37:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788734262; x=1789339062; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=WAPzz0F7ZYpxewku3mWPEkL5SYF6ac62winU6eKHPNw=; b=b6AL1OPiZkxwD4ZFJq9SxmsH6pR/3o5gYs94qiNe8WqAdKMZcXdjkmhDMmq/jntbG6 uORmP3OuqQ3P1WIrN8AXYMWwRDkK+kqxWmxEMl5N1QQo7wfnIN78rKZu3y8ALZ4G0Y9Y Ls1d/7RAFEhTsEot+IkNnuMgFhy8+NXRRwz71MLrC6TrSyvuf9KWoNQpcuukowzHDOKh mKcRBRgKyCvX9Zllb9716hFN11mf6dOhYOZmvEjc3mTFx5avXLgGbbo48pCjfRuy6mhX pkO4lobCz8osi6DoNxVHJSBf6f1Y84WGoi/p26wh8bqEfdTkKS+p1lIBv8xoJIjRSZwC WuQw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788734262; x=1789339062; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=WAPzz0F7ZYpxewku3mWPEkL5SYF6ac62winU6eKHPNw=; b=iPeQz3H7Duodo9UrRSz1NZYFZp5uVXedjfYtjF+p7RUZUd/aRMqSu0dCSTrirTnPeL a41N25/2FrTos6W1nREyvoNVbZS+XXCTI56N4414BmXUYw1H/kBDk91Xs+0xjnGhYDzm GUJbJMSeJm+9Ir5fBxlnAMIzIbAD3jKzXN0BHEsQNMliHMti4vSjN2DkPgYZQj6fFmnY GMzg8o4UFC14+ScWIgfjRC6gruskVw4nGsGLeRMgQMVM1puhOQTSmWK/iCifmV1A7cJ2 VeDS3y7xHUiG1UlHMmOmPJrR1V/rBTDw09aSKTOh094lu7w1o0EdnZN5c+BRBuMWXaZa AAqA== X-Forwarded-Encrypted: i=1; AKwUvBx9apD9zgO6/9Ue56Jubxn+PL2wqqhr9yxR2J6khho0QtC/m0r5R3wx9lugGe+Fux8NvFOhM7MCqKnj7Nk=@vger.kernel.org X-Gm-Message-State: AFuF++nYR/RkETn/9zB62924ODjHTA9uQWdHI2jnR3st8F8c45/zb6n9 jtNLPC1WJ7kXetqL0aeXSO8p/eGDhrfVeMHL+YDKvDnpZdlbTjIizwkf X-Gm-Gg: AYBFou0YTsgZplGKyDvkRrnrxFNYtFojooqxzQ6JkTxniaHn8ncjBBgQZ64Ok0NsL4S 1AKdTSnSi13dVirG7gZ/YTiCU+PdoS6M5nOV4h9JOQQoz5JscgcxzKfvmsZRVE0jp/6M9VIEjLY tYXb4ArYxJfZSURkZHD6OP90hygjC7BWA7PVFqQD5s50SWb3DuvXvLN1I9TdIgqW0w7Wv0E/4Eb e53WFEA+QeD9Iac8//wUu8AOaDI3pNdZWKKchEDLiKpMgn9CSj0Vbwtzp2t4cjPK9lrmYEZLH2j AuNiIJlCs+luLQLli5hIXscNEVmaIxW7eIpS82ZMWKOWEeI+ZHcf4AmrMKgw1YhWshUuZ6hY7r1 v3BpU1txZJfq76Vf99Ed7XQkgPlWLagNO0Zc7XxhBQPwINNCUoi4UKYuuyTvG2wEhOgjaHWNvty 2aUUSs4gDG+l6TXzZtfu46nGcbNGbFkzV77iQAzwFm8ib2cRwZwdFG0L5p4ichQCpE3F/ibMOcu ta7qL9oBg9SHcS7FYqRVYMczX8fsbE7wC3nsac6YQRdQo6tnKV0uFJ/joujibYao39GrNl6FnmF t7A/GulWKw== X-Received: by 2002:a05:600c:4f89:b0:49c:f617:7cf with SMTP id 5b1f17b1804b1-49cf7f32d0amr303208485e9.0.1788734261704; Sun, 06 Sep 2026 15:37:41 -0700 (PDT) Received: from kdev ([81.56.8.150]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49cf75ce49esm457882755e9.1.2026.09.06.15.37.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 06 Sep 2026 15:37:41 -0700 (PDT) From: Fabio Cesari To: Jonathan Cameron Cc: David Lechner , =?UTF-8?q?Nuno=20S=C3=A1?= , Andy Shevchenko , Brian Masney , Joshua Crofts , linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2] iio: light: isl29028: fix runtime PM reference leak on error paths Date: Mon, 7 Sep 2026 00:37:30 +0200 Message-ID: <20260906223737.206730-1-fabio.cesari@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260906131203.125407-1-fabio.cesari@gmail.com> References: <20260906131203.125407-1-fabio.cesari@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Both isl29028_read_raw() and isl29028_write_raw() take a runtime PM reference with pm_runtime_resume_and_get() and are supposed to drop it again with pm_runtime_put_autosuspend() before returning. On their error paths they return directly instead, leaking the reference. The usage count is then never balanced, so the device stops entering autosuspend for the rest of its lifetime. The effect accumulates: every failed access leaks another reference. In isl29028_write_raw() this is reachable from userspace with a single rejected sysfs write, for example echo 200 > in_proximity_sampling_frequency which is outside the accepted [1:100] range. It returns -EINVAL with the reference still held. In isl29028_read_raw() the leak is reached when the underlying regmap access fails. Take the reference with PM_RUNTIME_ACQUIRE_IF_ENABLED_AUTOSUSPEND() instead. It is then released when the function returns, on every path and without an explicit call, so no error path added later can leak it again. This also stops the result of pm_runtime_put_autosuspend() from reaching userspace, which fixes a second problem: that value reports whether the device could be suspended right away, so -EAGAIN or -EBUSY turned a successful access into a failure. With CONFIG_PM=n it is a stub returning -ENOSYS, so every read and write fails today. PM_RUNTIME_ACQUIRE_IF_ENABLED_AUTOSUSPEND() is v6.19 and later, so this does not apply as-is to older trees. The adjustment there is to keep pm_runtime_resume_and_get() and drop the reference on the way out with an unchecked pm_runtime_put_autosuspend(), which fixes both the leak and the return value. Fixes: 2db5054ac28d ("staging: iio: isl29028: add runtime power management support") Suggested-by: Joshua Crofts Cc: # see patch description, needs adjustments for < 6.19 Assisted-by: LLM coccinelle Signed-off-by: Fabio Cesari --- Changes in v2, from the review of v1: - take the reference with PM_RUNTIME_ACQUIRE_IF_ENABLED_AUTOSUSPEND() instead of balancing pm_runtime_put_autosuspend() by hand, so that its return value no longer reaches userspace either - use the Assisted-by form documented in coding-assistants.rst - move the note on how the bug was found below the --- v1: https://lore.kernel.org/linux-iio/20260906131203.125407-1-fabio.cesari@gmail.com/ Found by auditing IIO drivers with a Coccinelle semantic patch for runtime PM acquire/release imbalances. Compile-tested only: arm64 (native) and x86_64 (cross), defconfig plus CONFIG_SENSORS_ISL29028=m, plus an arm64 CONFIG_PM=n build to cover the stubs, with gcc 15.2.0, W=1 and sparse v0.6.5-rc1: no warnings. I have no isl29028 hardware, so this is untested at runtime. drivers/iio/light/isl29028.c | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/drivers/iio/light/isl29028.c b/drivers/iio/light/isl29028.c index 33deb1726689..03ad48930231 100644 --- a/drivers/iio/light/isl29028.c +++ b/drivers/iio/light/isl29028.c @@ -342,8 +342,9 @@ static int isl29028_write_raw(struct iio_dev *indio_dev, struct device *dev = regmap_get_device(chip->regmap); int ret; - ret = pm_runtime_resume_and_get(dev); - if (ret < 0) + PM_RUNTIME_ACQUIRE_IF_ENABLED_AUTOSUSPEND(dev, pm); + ret = PM_RUNTIME_ACQUIRE_ERR(&pm); + if (ret) return ret; mutex_lock(&chip->lock); @@ -392,14 +393,7 @@ static int isl29028_write_raw(struct iio_dev *indio_dev, mutex_unlock(&chip->lock); - if (ret < 0) - return ret; - - ret = pm_runtime_put_autosuspend(dev); - if (ret < 0) - return ret; - - return 0; + return ret; } static int isl29028_read_raw(struct iio_dev *indio_dev, @@ -408,10 +402,11 @@ static int isl29028_read_raw(struct iio_dev *indio_dev, { struct isl29028_chip *chip = iio_priv(indio_dev); struct device *dev = regmap_get_device(chip->regmap); - int ret, pm_ret; + int ret; - ret = pm_runtime_resume_and_get(dev); - if (ret < 0) + PM_RUNTIME_ACQUIRE_IF_ENABLED_AUTOSUSPEND(dev, pm); + ret = PM_RUNTIME_ACQUIRE_ERR(&pm); + if (ret) return ret; mutex_lock(&chip->lock); @@ -461,18 +456,6 @@ static int isl29028_read_raw(struct iio_dev *indio_dev, mutex_unlock(&chip->lock); - if (ret < 0) - return ret; - - /** - * Preserve the ret variable if the call to - * pm_runtime_put_autosuspend() is successful so the reading - * (if applicable) is returned to user space. - */ - pm_ret = pm_runtime_put_autosuspend(dev); - if (pm_ret < 0) - return pm_ret; - return ret; } base-commit: cee9395acd8043be0644b25c34bfa86623f2b935 -- 2.53.0