From: Fabio Cesari <fabio.cesari@gmail.com>
To: Jonathan Cameron <jic23@kernel.org>
Cc: "David Lechner" <dlechner@baylibre.com>,
"Nuno Sá" <nuno.sa@analog.com>,
"Andy Shevchenko" <andy@kernel.org>,
"Brian Masney" <bmasney@redhat.com>,
"Joshua Crofts" <joshua.crofts1@gmail.com>,
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 [thread overview]
Message-ID: <20260906223737.206730-1-fabio.cesari@gmail.com> (raw)
In-Reply-To: <20260906131203.125407-1-fabio.cesari@gmail.com>
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 <joshua.crofts1@gmail.com>
Cc: <stable@vger.kernel.org> # see patch description, needs adjustments for < 6.19
Assisted-by: LLM coccinelle
Signed-off-by: Fabio Cesari <fabio.cesari@gmail.com>
---
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
next prev parent reply other threads:[~2026-09-06 22:37 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-06 13:11 [PATCH] " Fabio Cesari
2026-09-06 13:55 ` Joshua Crofts
2026-09-06 22:09 ` Fabio Cesari
2026-09-06 17:43 ` Jonathan Cameron
2026-09-06 22:15 ` Fabio Cesari
2026-09-07 2:07 ` Jonathan Cameron
2026-09-07 7:29 ` Joshua Crofts
2026-09-09 16:21 ` Fabio Cesari
2026-09-06 22:37 ` Fabio Cesari [this message]
2026-09-07 7:19 ` [PATCH v2] " Joshua Crofts
2026-09-07 11:02 ` Fabio Cesari
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260906223737.206730-1-fabio.cesari@gmail.com \
--to=fabio.cesari@gmail.com \
--cc=andy@kernel.org \
--cc=bmasney@redhat.com \
--cc=dlechner@baylibre.com \
--cc=jic23@kernel.org \
--cc=joshua.crofts1@gmail.com \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=nuno.sa@analog.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®