mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: netdev-bot+sashiko@kernel.org
To: github@szelinsky.de
Cc: o.rempel@pengutronix.de, kory.maincent@bootlin.com,
	andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@kernel.org,
	kuba@kernel.org, pabeni@redhat.com, piotr.kubik@adtran.com,
	saikrishnag@marvell.com, horms@kernel.org, kyle.swenson@est.tech,
	netdev-bot+sashiko@kernel.org, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH net 04/10] net: pse-pd: do not reach a freed PHY from the notification worker
Date: Mon, 19 Oct 2026 08:51:12 +0000	[thread overview]
Message-ID: <179239987207.3135.17141454695480717442@kernel.org> (raw)
In-Reply-To: <20261018082314.48950-5-github@szelinsky.de>

Thank you for your contribution! Sashiko AI review found more severe
issue(s) in other patches of this series. This mail is only an FYI, in case
you want to address the nit picks below when you respin.

Low priority / nit picks for your consideration:

- [Low] The comment this patch adds to pse_send_ntf_worker()
  (drivers/net/pse-pd/pse_core.c, lines 1022-1028) says: "A pse_control…

Pre-existing issues:
- [High] This problem wasn't introduced by this patch, but
  phy_device_remove() (drivers/net/phy/phy_device.c:1155) calls…

--

net: pse-pd: do not reach a freed PHY from the notification worker

The notification worker used to take a reference on the pse_control. It
now looks up the pse_control under pse_list_mutex and uses
attached_phydev under that mutex, so a removed PHY cannot be reached. If
a second PHY takes a pse_control for a shared PI, attached_phydev is
cleared and a warning is printed.

> diff --git a/drivers/net/pse-pd/pse_core.c b/drivers/net/pse-pd/pse_core.c
> index 65a41c517b359..336f00d82b5f8 100644
> --- a/drivers/net/pse-pd/pse_core.c
> +++ b/drivers/net/pse-pd/pse_core.c

[ ... ]

> @@ -1020,13 +1019,21 @@ static void pse_send_ntf_worker(struct work_struct *work)
>  		struct net_device *netdev;
>  		struct pse_control *psec;
>  
> -		psec = pse_control_find_by_id(pcdev, ntf.id);
> +		/* A pse_control is only on the list while the PHY it was
> +		 * handed to holds it: the PHY's pse_control_put() unlinks
> +		 * and frees it under pse_list_mutex before the PHY itself
> +		 * can be freed. Holding the mutex across the lookup and the
> +		 * attached_phydev dereference therefore keeps the PHY alive,
> +		 * which a reference on the pse_control alone would not.
> +		 */

[Severity: Low]
This comment says a pse_control is only on the list while the PHY it was
handed to holds it, and that the PHY's pse_control_put() unlinks and frees
it. Does that hold when two PHYs share a PI?

In that case pse_control_get_internal() returns the existing psec after
kref_get(). The unlink and free only happen on the last put:

drivers/net/pse-pd/pse_core.c:__pse_control_release() {
    ...
	list_del(&psec->list);
	kfree(psec);
}

So the first PHY's phy_device_remove()->pse_control_put() only drops the
refcount. The psec stays on pcdev->pse_control_head after that PHY can be
freed.

The worker is still safe today, but only because
pse_control_get_internal() clears psec->attached_phydev when a different
PHY takes the psec. The comment gives list membership as the reason and
does not mention that dependency.

Could the comment say that it relies on attached_phydev being cleared in
the shared-PI case? Later patches in the series leave this comment
unchanged.

[ ... ]

> @@ -1417,6 +1424,19 @@ pse_control_get_internal(struct pse_controller_dev *pcdev, unsigned int index,
>  
>  	list_for_each_entry(psec, &pcdev->pse_control_head, list) {
>  		if (psec->id == index) {
> +			/* attached_phydev can only name one PHY. If a second
> +			 * one shares the PI, either may be removed first and
> +			 * leave it pointing at a freed phy_device, so stop
> +			 * reporting events for this PI instead.
> +			 */
> +			if (psec->attached_phydev &&
> +			    psec->attached_phydev != phydev) {
> +				dev_warn(pcdev->dev,
> +					 "PI %u shared by several PHYs, not reporting its events\n",
> +					 index);
> +				psec->attached_phydev = NULL;
> +			}
> +
>  			kref_get(&psec->refcnt);
>  			return psec;
>  		}

[Severity: High]
This is a pre-existing issue and was not introduced by this patch. This
patch relies on the pse_control_put() in phy_device_remove(). Does that
call leave phydev->psec dangling?

drivers/net/phy/phy_device.c:phy_device_remove() {
	unregister_mii_timestamper(phydev->mii_ts);
	pse_control_put(phydev->psec);

	device_del(&phydev->mdio.dev);
    ...
}

With the usual one PHY per PI, this put drops the last reference and
__pse_control_release() does list_del() and kfree(psec). phydev->psec is
never set to NULL.

The phy_device can outlive phy_device_remove(), because
phy_attach_direct() holds get_device() on it. The MAC<->PHY device_link
is DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS, so the MAC is not unbound.
phy_remove() also does not detach the netdev. After the MDIO bus is
unregistered or unbound under an attached MAC, netdev->phydev still
points at a phy_device whose psec has been freed.

ETHTOOL_MSG_PSE_GET does not need admin permissions, and it reaches:

pse_prepare_data()
  pse_get_pse_attributes()
    pse_ethtool_get_status(phydev->psec, ...)

net/ethtool/pse-pd.c:pse_get_pse_attributes() {
    ...
	if (!phydev->psec) {
		NL_SET_ERR_MSG(extack, "No PSE is attached");
		return -EOPNOTSUPP;
	}
    ...
	return pse_ethtool_get_status(phydev->psec, extack, &data->status);
}

Can this dereference the freed pse_control? The PSE SET handlers in
net/ethtool/pse-pd.c appear to follow the same pattern.

There may also be a race during removal. pse_control_put() in
phy_device_remove() runs without rtnl, but the ethtool handlers read
phydev->psec under rtnl. Could a concurrent PSE_GET or PSE_SET use the
psec while it is being freed?

Would clearing phydev->psec after the put, synchronized with the
rtnl-protected readers, address both cases? The pse_control_put() call in
phy_device_remove() dates back to commit 5e82147de1cbd7 in 2022. No later
patch in this series touches phy_device_remove() or the ethtool PSE
handlers.

-- 
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261018082314.48950-1-github%40szelinsky.de

  reply	other threads:[~2026-10-19  8:51 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-18  8:23 [PATCH net 00/10] net: pse-pd: assorted lifetime and error-path fixes Carlo Szelinsky
2026-10-18  8:23 ` [PATCH net 01/10] net: pse-pd: size the notification kfifo after defaulting nr_lines Carlo Szelinsky
2026-10-19  9:22   ` Kory Maincent
2026-10-18  8:23 ` [PATCH net 02/10] net: pse-pd: fix module refcount leak in pse_control_get_internal() Carlo Szelinsky
2026-10-19  8:51   ` netdev-bot+sashiko
2026-10-19  9:31   ` Kory Maincent
2026-10-18  8:23 ` [PATCH net 03/10] net: pse-pd: do not keep a failed IRQ in pcdev->irq Carlo Szelinsky
2026-10-19  9:33   ` Kory Maincent
2026-10-18  8:23 ` [PATCH net 04/10] net: pse-pd: do not reach a freed PHY from the notification worker Carlo Szelinsky
2026-10-19  8:51   ` netdev-bot+sashiko [this message]
2026-10-18  8:23 ` [PATCH net 05/10] net: pse-pd: check the PI state under the lock when setting a power limit Carlo Szelinsky
2026-10-19  8:51   ` netdev-bot+sashiko
2026-10-19 12:30     ` Kory Maincent
2026-10-18  8:23 ` [PATCH net 06/10] net: pse-pd: do not tie a shared power domain to its creator's devres Carlo Szelinsky
2026-10-19  8:51   ` netdev-bot+sashiko
2026-10-18  8:23 ` [PATCH net 07/10] net: pse-pd: pd692x0: release the manager power budget through devres Carlo Szelinsky
2026-10-19 12:45   ` Kory Maincent
2026-10-18  8:23 ` [PATCH net 08/10] net: pse-pd: pd692x0: defer probe while a manager supply is unresolved Carlo Szelinsky
2026-10-19 12:47   ` Kory Maincent
2026-10-18  8:23 ` [PATCH net 09/10] net: pse-pd: si3474: fix use-after-free in ancillary client error path Carlo Szelinsky
2026-10-19 12:50   ` Kory Maincent
2026-10-18  8:23 ` [PATCH net 10/10] net: pse-pd: reject a power limit whose current does not fit an int Carlo Szelinsky
2026-10-19 12:53   ` Kory Maincent
2026-10-18 23:32 ` [PATCH net 00/10] net: pse-pd: assorted lifetime and error-path fixes Ross Cawston

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=179239987207.3135.17141454695480717442@kernel.org \
    --to=netdev-bot+sashiko@kernel.org \
    --cc=andrew+netdev@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@kernel.org \
    --cc=github@szelinsky.de \
    --cc=horms@kernel.org \
    --cc=kory.maincent@bootlin.com \
    --cc=kuba@kernel.org \
    --cc=kyle.swenson@est.tech \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=o.rempel@pengutronix.de \
    --cc=pabeni@redhat.com \
    --cc=piotr.kubik@adtran.com \
    --cc=saikrishnag@marvell.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®