All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jakub Kicinski <kuba@kernel.org>
To: ahmadexp@gmail.com
Cc: Jakub Kicinski <kuba@kernel.org>,
	netdev@vger.kernel.org, lee@kernel.org, pavel@kernel.org,
	robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
	andi.shyti@kernel.org, peda@lysator.liu.se, trannamatk@gmail.com,
	vadim.fedorenko@linux.dev, richardcochran@gmail.com,
	andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
	pabeni@redhat.com, kees@kernel.org, gustavoars@kernel.org,
	linux-leds@vger.kernel.org, devicetree@vger.kernel.org,
	linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-hardening@vger.kernel.org
Subject: Re: [PATCH net-next v5 3/7] i2c: mux: Propagate software nodes to channel adapters
Date: Tue, 18 Aug 2026 09:57:15 -0700	[thread overview]
Message-ID: <20260818165715.4008405-1-kuba@kernel.org> (raw)
In-Reply-To: <a758b93f394ecfd4dfa65517782530d4a8c45e39.1786747084.git.ahmadexp@gmail.com>

This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
---
i2c: mux: Propagate software nodes to channel adapters

This attaches the matching software-node child of the mux device to each
i2c-mux channel adapter, tracks whether the mux owns that attachment for
cleanup, and extends the I2C firmware-node adapter lookup so it also
matches a device's secondary fwnode.

> diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
> index 3ec04787a7373..f39575ee02444 100644
> --- a/drivers/i2c/i2c-core-base.c
> +++ b/drivers/i2c/i2c-core-base.c
> @@ -1876,12 +1876,22 @@ int devm_i2c_add_adapter(struct device *dev, struct i2c_adapter *adapter)
>  }
>  EXPORT_SYMBOL_GPL(devm_i2c_add_adapter);
>  
> -static int i2c_dev_or_parent_fwnode_match(struct device *dev, const void *data)
> +static bool i2c_device_match_fwnode(struct device *dev, const void *data)
>  {
> +	struct fwnode_handle *fwnode = dev_fwnode(dev);
> +
>  	if (device_match_fwnode(dev, data))
> +		return true;
> +
> +	return !IS_ERR_OR_NULL(fwnode) && fwnode->secondary == data;
> +}

[Severity: Medium]
Is the new fwnode->secondary dereference safe here?  The old code only used
device_match_fwnode(), which compares pointers and never dereferences the
fwnode.

i2c_dev_or_parent_fwnode_match() runs as a bus_find_device() match callback
from i2c_find_adapter_by_fwnode()/i2c_get_adapter_by_fwnode(), so it is
invoked for every device on i2c_bus_type, including clients, with no
device_lock held and nothing pinning dev->fwnode.

Meanwhile i2c_unregister_device() detaches and frees the software node
while the client is still in the bus klist:

drivers/i2c/i2c-core-base.c:i2c_unregister_device() {
	...
	device_remove_software_node(&client->dev);
	device_unregister(&client->dev);
}

For a client created with info->swnode and no primary fwnode,
dev->fwnode == &swnode->fwnode, and device_remove_software_node() drops the
last reference:

drivers/base/swnode.c:device_remove_software_node() {
	...
	set_secondary_fwnode(dev, NULL);
	swnode_put(swnode);
}

Can a lookup then observe fwnode = dev_fwnode(dev) before the free and read
fwnode->secondary after it?  The writers are unsynchronized too:

drivers/base/core.c:set_secondary_fwnode() {
	if (fwnode_is_primary(dev->fwnode))
		dev->fwnode->secondary = fwnode;
	else
		dev->fwnode = fwnode;
}

There is no lock common to the reader and the writer and no WRITE_ONCE, so
this also looks like a plain data race that could make the lookup return an
adapter whose software node has already been detached.

Also, does the extra dereference help in that case at all?  A software node
installed in the primary slot always has secondary == ERR_PTR(-ENODEV), so
it can never match through fwnode->secondary; only the window seems new.

> @@ -1891,8 +1901,9 @@ static int i2c_dev_or_parent_fwnode_match(struct device *dev, const void *data)

[ ... ]

> diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c
> index 681a201c239ba..3bca123907b3d 100644
> --- a/drivers/i2c/i2c-mux.c
> +++ b/drivers/i2c/i2c-mux.c

[ ... ]

> @@ -364,6 +417,8 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
>  
>  		priv->adap.dev.of_node = child;
>  		of_node_put(mux_node);
> +	} else {
> +		channel_node = i2c_mux_get_channel_swnode(muxc, chan_id);
>  	}
>  
>  	/*

[ ... ]

> @@ -408,6 +473,8 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
>  	return 0;
>  
>  err_free_priv:
> +	if (priv->swnode)
> +		device_remove_software_node(&priv->adap.dev);
>  	kfree(priv);
>  	return ret;
>  }

[Severity: Medium]
This isn't a bug introduced by this patch, but since err_free_priv is being
extended here, should it also drop the DT channel node reference?

In the DT branch of i2c_mux_add_adapter(), priv->adap.dev.of_node holds a
reference obtained either from the for_each_child_of_node() early break, or
from of_node_get(dev_node)/of_node_get(mux_node).  When
i2c_add_adapter()/i2c_add_numbered_adapter() fails, control reaches
err_free_priv, which only does kfree(priv).

That the mux owns that reference is visible in the success-path teardown,
which saves np = adap->dev.of_node and puts it after i2c_del_adapter():

> @@ -429,7 +496,13 @@ void i2c_mux_del_adapters(struct i2c_mux_core *muxc)
>  		sysfs_remove_link(&priv->adap.dev.kobj, "mux_device");
> +		/*
> +		 * Keep the software node through child removal. The adapter
> +		 * device is cleared on deletion, so release the software-node
> +		 * attachment reference via the saved handle afterwards.
> +		 */
>  		i2c_del_adapter(adap);
> +		fwnode_handle_put(priv->swnode);
>  		of_node_put(np);
>  		kfree(priv);
>  	}

Neither i2c_register_adapter()'s error labels nor the driver core drops a
device's of_node reference when device_add() fails, so does the failure path
leak that struct device_node reference?  Would adding
of_node_put(priv->adap.dev.of_node) at err_free_priv be appropriate while
this label is being touched?

  parent reply	other threads:[~2026-08-18 16:57 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-14 23:10 [PATCH net-next v5 0/7] ptp: ocp: Add R4006 and V9 I2C peripheral support Ahmad Byagowi
2026-08-14 23:10 ` [PATCH net-next v5 1/7] dt-bindings: leds: Add IS32FL3207 controller Ahmad Byagowi
2026-08-15 23:11   ` sashiko-bot
2026-08-17  6:41   ` Krzysztof Kozlowski
2026-08-17 18:06     ` Ahmad Byagowi
2026-08-18 16:57   ` Jakub Kicinski
2026-08-14 23:10 ` [PATCH net-next v5 2/7] leds: is32fl3207: Add controller driver Ahmad Byagowi
2026-08-15 23:11   ` sashiko-bot
2026-08-18 16:57   ` Jakub Kicinski
2026-08-14 23:10 ` [PATCH net-next v5 3/7] i2c: mux: Propagate software nodes to channel adapters Ahmad Byagowi
2026-08-15 23:11   ` sashiko-bot
2026-08-18 16:57   ` Jakub Kicinski [this message]
2026-08-14 23:10 ` [PATCH net-next v5 4/7] ptp: ocp: Track EEPROM fields independently Ahmad Byagowi
2026-08-15 23:11   ` sashiko-bot
2026-08-18 16:57   ` Jakub Kicinski
2026-08-14 23:10 ` [PATCH net-next v5 5/7] ptp: ocp: Add profile-driven I2C topology support Ahmad Byagowi
2026-08-15 23:11   ` sashiko-bot
2026-08-18 16:57   ` Jakub Kicinski
2026-08-14 23:10 ` [PATCH net-next v5 6/7] ptp: ocp: Add R4006 I2C peripheral topology Ahmad Byagowi
2026-08-15 23:11   ` sashiko-bot
2026-08-18 16:57   ` Jakub Kicinski
2026-08-14 23:10 ` [PATCH net-next v5 7/7] ptp: ocp: Add Time Card V9 " Ahmad Byagowi
2026-08-15 23:11   ` sashiko-bot
2026-08-18 16:57   ` Jakub Kicinski
2026-08-18 16:56 ` [PATCH net-next v5 0/7] ptp: ocp: Add R4006 and V9 I2C peripheral support Jakub Kicinski
2026-08-18 18:12   ` Ahmad Byagowi

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=20260818165715.4008405-1-kuba@kernel.org \
    --to=kuba@kernel.org \
    --cc=ahmadexp@gmail.com \
    --cc=andi.shyti@kernel.org \
    --cc=andrew+netdev@lunn.ch \
    --cc=conor+dt@kernel.org \
    --cc=davem@davemloft.net \
    --cc=devicetree@vger.kernel.org \
    --cc=edumazet@google.com \
    --cc=gustavoars@kernel.org \
    --cc=kees@kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=lee@kernel.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-i2c@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-leds@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=pavel@kernel.org \
    --cc=peda@lysator.liu.se \
    --cc=richardcochran@gmail.com \
    --cc=robh@kernel.org \
    --cc=trannamatk@gmail.com \
    --cc=vadim.fedorenko@linux.dev \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.