[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <aO12r9v4xaJKHUQs@lizhi-Precision-Tower-5810>
Date: Mon, 13 Oct 2025 18:01:19 -0400
From: Frank Li <Frank.li@....com>
To: Shuhao Fu <sfual@....ust.hk>
Cc: Alexandre Belloni <alexandre.belloni@...tlin.com>,
linux-i3c@...ts.infradead.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH] i3c: fix refcount inconsistency in i3c_master_register
On Tue, Oct 14, 2025 at 05:09:53AM +0800, Shuhao Fu wrote:
> On Mon, Oct 13, 2025 at 04:19:00PM -0400, Frank Li wrote:
> > On Fri, Oct 10, 2025 at 02:34:08PM +0800, Shuhao Fu wrote:
> > > On Thu, Oct 09, 2025 at 12:17:11PM -0400, Frank Li wrote:
> > > > On Wed, Oct 08, 2025 at 03:27:09PM +0800, Shuhao Fu wrote:
> > > > > In `i3c_master_register`, a possible refcount inconsistency has been
> > > > > identified, causing possible resource leak.
> > > > >
> > > > > Function `of_node_get` increases the refcount of `parent->of_node`. If
> > > > > function `i3c_bus_init` fails, the function returns immediately without
> > > > > a corresponding decrease, resulting in an inconsistent refcounter.
> > > > >
> > > > > In this patch, an extra goto label is added to ensure the balance of
> > > > > refcount when `i3c_bus_init` fails.
> > > > >
> > > > > Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure")
> > > > > Signed-off-by: Shuhao Fu <sfual@....ust.hk>
> > > > > ---
> > > > > drivers/i3c/master.c | 5 ++++-
> > > > > 1 file changed, 4 insertions(+), 1 deletion(-)
> > > > >
> > > > > diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
> > > > > index d946db75d..9f4fe98d2 100644
> > > > > --- a/drivers/i3c/master.c
> > > > > +++ b/drivers/i3c/master.c
> > > > > @@ -2885,7 +2885,7 @@ int i3c_master_register(struct i3c_master_controller *master,
> > > > >
> > > > > ret = i3c_bus_init(i3cbus, master->dev.of_node);
> > > > > if (ret)
> > > > > - return ret;
> > > > > + goto err_put_of_node;
> > > >
> > > > I think it'd better to set release function for master dev to release
> > > > of_node because of_node_put() also missed at i3c_master_unregister()
> > > >
> > > > you can refer drivers/base/platform.c
> > > >
> > > > Frank
> > >
> > > Do you mean that we should do `of_node_release` in
> > > `platform_device_release`, instead of respecting the refcounting via
> > > `of_node_put`?
> >
> > Sorry, I checked code again.
> >
> > static void i3c_masterdev_release(struct device *dev)
> > {
> > ...
> > of_node_put(dev->of_node);
> > }
> >
> > i3c_master_register()
> > {
> > ...
> > master->dev.release = i3c_masterdev_release;
> > ...
> > };
> >
> > Suppose of_node_put() will be auto called when put_device(&master->dev);
> >
> > Do you really meet the problem or just static anaysis?
> >
> > Frank
>
> Honestly, it's from static analysis.
>
> My apologies for overlooking the release handle. I checked the code once
> again. It still looks suspicious as it would not call `put_device` if it
> fails. I also checked call sites related to `i3c_master_register` and
> they dont seem to do the clean-up if register fails.
@@ -2814,10 +2816,6 @@ int i3c_master_register(struct i3c_master_controller *master,
INIT_LIST_HEAD(&master->boardinfo.i2c);
INIT_LIST_HEAD(&master->boardinfo.i3c);
- ret = i3c_bus_init(i3cbus, master->dev.of_node);
- if (ret)
- return ret;
-
device_initialize(&master->dev);
dev_set_name(&master->dev, "i3c-%d", i3cbus->id);
@@ -2825,6 +2823,10 @@ int i3c_master_register(struct i3c_master_controller *master,
master->dev.coherent_dma_mask = parent->coherent_dma_mask;
master->dev.dma_parms = parent->dma_parms;
+ ret = i3c_bus_init(i3cbus, master->dev.of_node);
+ if (ret)
+ goto err_put_dev;
+
I inject at error at i3c_bus_init(), above code can trigger i3c_masterdev_release,
which call of_node_put().
Frank
>
> Shuhao
> > >
> > > >
> > > > >
> > > > > device_initialize(&master->dev);
> > > > > dev_set_name(&master->dev, "i3c-%d", i3cbus->id);
> > > > > @@ -2973,6 +2973,9 @@ int i3c_master_register(struct i3c_master_controller *master,
> > > > > err_put_dev:
> > > > > put_device(&master->dev);
> > > > >
> > > > > +err_put_of_node:
> > > > > + of_node_put(master->dev.of_node);
> > > > > +
> > > > > return ret;
> > > > > }
> > > > > EXPORT_SYMBOL_GPL(i3c_master_register);
> > > > > --
> > > > > 2.39.5 (Apple Git-154)
> > > > >
> > > > >
> > > > > --
> > > > > linux-i3c mailing list
> > > > > linux-i3c@...ts.infradead.org
> > > > > http://lists.infradead.org/mailman/listinfo/linux-i3c
> > >
> > > --
> > > linux-i3c mailing list
> > > linux-i3c@...ts.infradead.org
> > > http://lists.infradead.org/mailman/listinfo/linux-i3c
Powered by blists - more mailing lists