Linux kernel -stable discussions
 help / color / mirror / Atom feed
* [PATCH v2 1/8] driver core: platform: fix swnode use-after-free on device release
       [not found] <20261110085125.2535508-1-johan@kernel.org>
@ 2026-11-10  8:51 ` Johan Hovold
  2026-11-10  8:51 ` [PATCH v2 2/8] i2c: core: fix swnode use-after-free on client deregistration Johan Hovold
  1 sibling, 0 replies; 4+ messages in thread
From: Johan Hovold @ 2026-11-10  8:51 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
	Johan Hovold
  Cc: Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
	Bartosz Golaszewski, Andi Shyti, driver-core, linux-acpi,
	linux-i2c, linux-kernel, stable, Bartosz Golaszewski

When a device has a software node, device_remove_software_node() may
drop the last reference and free it during platform_device_release().
If the software node is the also the primary node then the device fwnode
pointer is never cleared.

Use a temporary variable to track whether the firmware node is a
software node to avoid a use-after-free in is_software_node() and having
fwnode_handle_put() call a function pointer via poisoned or reallocated
memory when the primary node is a software node.

This issue was flagged by Sashiko when reviewing a related fix.

Fixes: 7d80509ff0da ("driver core: platform: unify release path")
Closes: https://sashiko.dev/#/bug/linux-b860000b-f1d0-46a0-ab52-d47cec8eab99
Cc: stable@vger.kernel.org	# 7.3
Cc: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
---
 drivers/base/platform.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 979593e5cca1..be5d2f315fdb 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -598,13 +598,14 @@ static void platform_device_release(struct device *dev)
 {
 	struct platform_object *pa = container_of(dev, struct platform_object,
 						  pdev.dev);
+	bool fwnode_is_software_node = is_software_node(dev_fwnode(dev));
 
 	device_remove_software_node(dev);
 	/*
-	 * If the primary firmware node is a software node, its reference count
-	 * was already decreased by the call to device_remove_software_node().
+	 * If the firmware node is a software node, its reference count
+	 * was decremented by device_remove_software_node().
 	 */
-	if (!is_software_node(dev_fwnode(dev)))
+	if (!fwnode_is_software_node)
 		fwnode_handle_put(pa->pdev.dev.fwnode);
 	kfree(pa->pdev.dev.platform_data);
 	kfree(pa->pdev.mfd_cell);
-- 
2.56.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 2/8] i2c: core: fix swnode use-after-free on client deregistration
       [not found] <20261110085125.2535508-1-johan@kernel.org>
  2026-11-10  8:51 ` [PATCH v2 1/8] driver core: platform: fix swnode use-after-free on device release Johan Hovold
@ 2026-11-10  8:51 ` Johan Hovold
  2026-11-10 10:58   ` Andy Shevchenko
  1 sibling, 1 reply; 4+ messages in thread
From: Johan Hovold @ 2026-11-10  8:51 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
	Johan Hovold
  Cc: Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
	Bartosz Golaszewski, Andi Shyti, driver-core, linux-acpi,
	linux-i2c, linux-kernel, stable, Hans de Goede

If a client has both a primary and a secondary firmware node, the
secondary node is accessed via the ->secondary pointer of the primary
node.

Use a temporary variable to track whether the firmware node is a
software node and remove any software node before dropping its reference
to avoid a use-after-free in device_remove_software_node() when
accessing the secondary firmware node.

Fixes: df6d7277e552 ("i2c: core: Do not dereference fwnode in struct device")
Fixes: 1c24e5fc0c70 ("i2c: core: Fix double-free of fwnode in i2c_unregister_device()")
Cc: stable@vger.kernel.org	# 6.16
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Hans de Goede <hansg@kernel.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
---
 drivers/i2c/i2c-core-base.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index 81603317b64d..c55ca14eaad9 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -1056,6 +1056,7 @@ EXPORT_SYMBOL_GPL(i2c_new_client_device);
 void i2c_unregister_device(struct i2c_client *client)
 {
 	struct fwnode_handle *fwnode;
+	bool fwnode_is_software_node;
 
 	if (IS_ERR_OR_NULL(client))
 		return;
@@ -1066,14 +1067,14 @@ void i2c_unregister_device(struct i2c_client *client)
 	else if (is_acpi_device_node(fwnode))
 		acpi_device_clear_enumerated(to_acpi_device_node(fwnode));
 
+	fwnode_is_software_node = is_software_node(fwnode);
+	device_remove_software_node(&client->dev);
 	/*
-	 * If the primary fwnode is a software node it is free-ed by
-	 * device_remove_software_node() below, avoid double-free.
+	 * If the firmware node is a software node, its reference count
+	 * was decremented by device_remove_software_node().
 	 */
-	if (!is_software_node(fwnode))
+	if (!fwnode_is_software_node)
 		fwnode_handle_put(fwnode);
-
-	device_remove_software_node(&client->dev);
 	device_unregister(&client->dev);
 }
 EXPORT_SYMBOL_GPL(i2c_unregister_device);
-- 
2.56.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2 2/8] i2c: core: fix swnode use-after-free on client deregistration
  2026-11-10  8:51 ` [PATCH v2 2/8] i2c: core: fix swnode use-after-free on client deregistration Johan Hovold
@ 2026-11-10 10:58   ` Andy Shevchenko
  2026-11-10 11:15     ` Johan Hovold
  0 siblings, 1 reply; 4+ messages in thread
From: Andy Shevchenko @ 2026-11-10 10:58 UTC (permalink / raw)
  To: Johan Hovold
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
	Daniel Scally, Heikki Krogerus, Sakari Ailus, Bartosz Golaszewski,
	Andi Shyti, driver-core, linux-acpi, linux-i2c, linux-kernel,
	stable, Hans de Goede

On Tue, Nov 10, 2026 at 09:51:18AM +0100, Johan Hovold wrote:
> If a client has both a primary and a secondary firmware node, the
> secondary node is accessed via the ->secondary pointer of the primary
> node.
> 
> Use a temporary variable to track whether the firmware node is a
> software node and remove any software node before dropping its reference
> to avoid a use-after-free in device_remove_software_node() when
> accessing the secondary firmware node.

...

> Fixes: df6d7277e552 ("i2c: core: Do not dereference fwnode in struct device")
> Fixes: 1c24e5fc0c70 ("i2c: core: Fix double-free of fwnode in i2c_unregister_device()")
> Cc: stable@vger.kernel.org	# 6.16

> Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Cc: Hans de Goede <hansg@kernel.org>

Can we keep these two Cc out of the commit message?

> Signed-off-by: Johan Hovold <johan@kernel.org>
> ---

...

>  	struct fwnode_handle *fwnode;
> +	bool fwnode_is_software_node;
>  
>  	if (IS_ERR_OR_NULL(client))
>  		return;
> @@ -1066,14 +1067,14 @@ void i2c_unregister_device(struct i2c_client *client)
>  	else if (is_acpi_device_node(fwnode))
>  		acpi_device_clear_enumerated(to_acpi_device_node(fwnode));
>  
> +	fwnode_is_software_node = is_software_node(fwnode);
> +	device_remove_software_node(&client->dev);
>  	/*
> -	 * If the primary fwnode is a software node it is free-ed by
> -	 * device_remove_software_node() below, avoid double-free.
> +	 * If the firmware node is a software node, its reference count
> +	 * was decremented by device_remove_software_node().
>  	 */
> -	if (!is_software_node(fwnode))
> +	if (!fwnode_is_software_node)
>  		fwnode_handle_put(fwnode);

Do I understand correctly that this is a dup with the platform device case? Can
we make a helper (on swnode API level) to cover any other existing or potential
case to avoid similar issues in the future?

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2 2/8] i2c: core: fix swnode use-after-free on client deregistration
  2026-11-10 10:58   ` Andy Shevchenko
@ 2026-11-10 11:15     ` Johan Hovold
  0 siblings, 0 replies; 4+ messages in thread
From: Johan Hovold @ 2026-11-10 11:15 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
	Daniel Scally, Heikki Krogerus, Sakari Ailus, Bartosz Golaszewski,
	Andi Shyti, driver-core, linux-acpi, linux-i2c, linux-kernel,
	stable, Hans de Goede

On Tue, Nov 10, 2026 at 12:58:15PM +0200, Andy Shevchenko wrote:
> On Tue, Nov 10, 2026 at 09:51:18AM +0100, Johan Hovold wrote:
> > If a client has both a primary and a secondary firmware node, the
> > secondary node is accessed via the ->secondary pointer of the primary
> > node.
> > 
> > Use a temporary variable to track whether the firmware node is a
> > software node and remove any software node before dropping its reference
> > to avoid a use-after-free in device_remove_software_node() when
> > accessing the secondary firmware node.
> 
> ...
> 
> > Fixes: df6d7277e552 ("i2c: core: Do not dereference fwnode in struct device")
> > Fixes: 1c24e5fc0c70 ("i2c: core: Fix double-free of fwnode in i2c_unregister_device()")
> > Cc: stable@vger.kernel.org	# 6.16
> 
> > Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> > Cc: Hans de Goede <hansg@kernel.org>
> 
> Can we keep these two Cc out of the commit message?

I prefer to highlight the authors of the commits mentioned in the Fixes
tag this way.

> > Signed-off-by: Johan Hovold <johan@kernel.org>
> > ---

> > @@ -1066,14 +1067,14 @@ void i2c_unregister_device(struct i2c_client *client)
> >  	else if (is_acpi_device_node(fwnode))
> >  		acpi_device_clear_enumerated(to_acpi_device_node(fwnode));
> >  
> > +	fwnode_is_software_node = is_software_node(fwnode);
> > +	device_remove_software_node(&client->dev);
> >  	/*
> > -	 * If the primary fwnode is a software node it is free-ed by
> > -	 * device_remove_software_node() below, avoid double-free.
> > +	 * If the firmware node is a software node, its reference count
> > +	 * was decremented by device_remove_software_node().
> >  	 */
> > -	if (!is_software_node(fwnode))
> > +	if (!fwnode_is_software_node)
> >  		fwnode_handle_put(fwnode);
> 
> Do I understand correctly that this is a dup with the platform device case? Can
> we make a helper (on swnode API level) to cover any other existing or potential
> case to avoid similar issues in the future?

The bug is different, but the fix is the same. This all gets cleaned up
in patch 4/8.

Johan

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-11-10 11:15 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20261110085125.2535508-1-johan@kernel.org>
2026-11-10  8:51 ` [PATCH v2 1/8] driver core: platform: fix swnode use-after-free on device release Johan Hovold
2026-11-10  8:51 ` [PATCH v2 2/8] i2c: core: fix swnode use-after-free on client deregistration Johan Hovold
2026-11-10 10:58   ` Andy Shevchenko
2026-11-10 11:15     ` Johan Hovold

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox