From: "Alvin Šipraga" <alvin.sipraga@analog.com>
To: development@redaril.me
Cc: Peter Rosin <peda@lysator.liu.se>,
Linus Walleij <linusw@kernel.org>,
linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org,
xu.yang_2@nxp.com
Subject: Re: [PATCH v3 3/3] mux: Avoid use-after-free of args.fwnode in mux_get()
Date: Wed, 30 Sep 2026 11:45:37 +0200 [thread overview]
Message-ID: <arzY2haHccIweQah@analog.com> (raw)
In-Reply-To: <20260929-mux_fwnode-v3-3-9b3b9ae1334e@redaril.me>
On Tue, Sep 29, 2026 at 10:51:48PM +0200, Fabio Forni via B4 Relay wrote:
> From: Fabio Forni <development@redaril.me>
>
> fwnode_handle_put(args.fwnode) was called right after
> mux_chip_find_by_fwnode(), but it was too early because the error
> handling code below would pass args.fwnode to dev_err().
> Let's move all freeing functions to the bottom of mux_get() to avoid
> use-after-free bugs.
>
> Signed-off-by: Fabio Forni <development@redaril.me>
I meant to suggest that you apply this fix before your fwnode patch, so
that it can be applied to the stable trees. Since you put the fix
afterwards, it either needs backporting, or the fwnode patch needs to be
carried too.
You might also want a Fixes: tag for it to actually get picked up for
stable.
Up to Peter though - it's a minor bug and the kernel has tons of such
refcounting bloopers. As far as the code is concerned it looks fine
(minor nit below). Thanks!
Reviewed-by: Alvin Šipraga <alvin.sipraga@analog.com>
> ---
> drivers/mux/core.c | 29 ++++++++++++++++++++---------
> 1 file changed, 20 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/mux/core.c b/drivers/mux/core.c
> index d5121772c483..8bf8c79bc634 100644
> --- a/drivers/mux/core.c
> +++ b/drivers/mux/core.c
> @@ -545,6 +545,9 @@ static struct mux_chip *mux_chip_find_by_fwnode(struct fwnode_handle *fwnode)
> * @optional: Whether to return NULL and silence errors when mux doesn't exist.
> * @node: the device nodes, use dev's fwnode if it is NULL.
> *
> + * When a mux-control is found, it is the caller's responsibility to call
> + * mux_control_put() on it when it is no longer needed.
> + *
> * Return: Pointer to the mux-control on success, an ERR_PTR with a negative
> * errno on error, or NULL if optional is true and mux doesn't exist.
> */
> @@ -597,9 +600,10 @@ static struct mux_control *mux_get(struct device *dev, const char *mux_name,
> }
>
> mux_chip = mux_chip_find_by_fwnode(args.fwnode);
> - fwnode_handle_put(args.fwnode);
> - if (!mux_chip)
> - return ERR_PTR(-EPROBE_DEFER);
> + if (!mux_chip) {
> + ret = -EPROBE_DEFER;
> + goto end;
> + }
>
> controller = 0;
> if (state) {
> @@ -607,8 +611,8 @@ static struct mux_control *mux_get(struct device *dev, const char *mux_name,
> (args.nargs < 2 && mux_chip->controllers > 1)) {
> dev_err(dev, "%pfw: wrong #mux-state-cells for %pfw\n",
> fwnode, args.fwnode);
> - put_device(&mux_chip->dev);
> - return ERR_PTR(-EINVAL);
> + ret = -EINVAL;
> + goto end;
> }
>
> if (args.nargs == 2) {
> @@ -623,8 +627,8 @@ static struct mux_control *mux_get(struct device *dev, const char *mux_name,
> (!args.nargs && mux_chip->controllers > 1)) {
> dev_err(dev, "%pfw: wrong #mux-control-cells for %pfw\n",
> fwnode, args.fwnode);
> - put_device(&mux_chip->dev);
> - return ERR_PTR(-EINVAL);
> + ret = -EINVAL;
> + goto end;
> }
>
> if (args.nargs)
> @@ -634,10 +638,17 @@ static struct mux_control *mux_get(struct device *dev, const char *mux_name,
> if (controller >= mux_chip->controllers) {
> dev_err(dev, "%pfw: bad mux controller %u specified in %pfw\n",
> fwnode, controller, args.fwnode);
> - put_device(&mux_chip->dev);
> - return ERR_PTR(-EINVAL);
> + ret = -EINVAL;
> + goto end;
> }
>
> +end:
> + fwnode_handle_put(args.fwnode);
> + if (ret < 0) {
> + if (mux_chip)
> + put_device(&mux_chip->dev);
> + return ERR_PTR(ret);
> + }
> return &mux_chip->mux[controller];
(nit) A newline between the above } and return would be nice.
> }
>
>
> --
> 2.55.0
>
>
next prev parent reply other threads:[~2026-09-30 9:46 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-29 20:51 [PATCH v3 0/3] Migrate the multiplexer subsystem to fwnode Fabio Forni via B4 Relay
2026-09-29 20:51 ` [PATCH v3 1/3] mux: convert to use fwnode interface Fabio Forni via B4 Relay
2026-09-30 9:39 ` Alvin Šipraga
2026-09-29 20:51 ` [PATCH v3 2/3] mux: Document mux_chip_find_by_fwnode() Fabio Forni via B4 Relay
2026-09-30 9:39 ` Alvin Šipraga
2026-09-29 20:51 ` [PATCH v3 3/3] mux: Avoid use-after-free of args.fwnode in mux_get() Fabio Forni via B4 Relay
2026-09-30 9:45 ` Alvin Šipraga [this message]
2026-09-30 17:44 ` Fabio
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=arzY2haHccIweQah@analog.com \
--to=alvin.sipraga@analog.com \
--cc=development@redaril.me \
--cc=linusw@kernel.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=peda@lysator.liu.se \
--cc=xu.yang_2@nxp.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®