* [PATCH net 0/3] ionic: fix port_info lifetime problems around device reset
@ 2026-08-15 0:00 Eric Joyner
2026-08-15 0:00 ` [PATCH net 1/3] ionic: check for a NULL port_info in the remaining ethtool ops Eric Joyner
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Eric Joyner @ 2026-08-15 0:00 UTC (permalink / raw)
To: netdev
Cc: Brett Creeley, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Nikhil P. Rao, Eric Joyner
The ionic port_info DMA buffer is read by most of the driver's ethtool
ops, and is freed and reallocated by the firmware recovery and PCI reset
paths. Those paths hold no lock that the ethtool ops honor - the
driver takes no rtnl anywhere - so ethtool can dereference a pointer
that has just been set to NULL, or read out of a buffer that has just
been freed.
Patch 1 adds the missing NULL checks to the six ethtool ops that lacked
them; ionic_get_link_ext_stats() and ionic_get_link_ksettings() already
had them. It fixes the oops reachable today and does not depend on the
other two, so it stands on its own if the approach in patch 2 needs
more discussion.
Patch 2 detaches the netdev in ionic_reset_prepare(). The ethtool core
only stays out of a driver when netif_device_present() is false, and the
firmware recovery path already relies on that; the PCI reset path never
did. This is what actually closes the window rather than papering over
it.
Patch 3 fixes an unrelated leak of the same buffer that turned up while
auditing the free paths: probe failures after the port has been set up
unwind through a label that never calls ionic_port_reset().
The port_info lifetime problems were pointed out by the netdev AI review
bot on an unrelated ionic ethtool patch:
https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260731214021.15279-1-eric.joyner@amd.com
Signed-off-by: Eric Joyner <eric.joyner@amd.com>
---
Eric Joyner (3):
ionic: check for a NULL port_info in the remaining ethtool ops
ionic: detach the netdev in the PCI reset handler
ionic: free port_info when probe fails after the port is set up
.../net/ethernet/pensando/ionic/ionic_bus_pci.c | 2 ++
.../net/ethernet/pensando/ionic/ionic_ethtool.c | 30 ++++++++++++++++++++++
2 files changed, 32 insertions(+)
---
base-commit: 24ef02f934eeb48830cff6b739abc3c62b1d107b
change-id: 20260814-ionic-port-info-lifetime-3163779cb298
Best regards,
--
Eric Joyner <eric.joyner@amd.com>
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH net 1/3] ionic: check for a NULL port_info in the remaining ethtool ops 2026-08-15 0:00 [PATCH net 0/3] ionic: fix port_info lifetime problems around device reset Eric Joyner @ 2026-08-15 0:00 ` Eric Joyner 2026-08-15 22:39 ` Vadim Fedorenko 2026-08-15 0:00 ` [PATCH net 2/3] ionic: detach the netdev in the PCI reset handler Eric Joyner 2026-08-15 0:00 ` [PATCH net 3/3] ionic: free port_info when probe fails after the port is set up Eric Joyner 2 siblings, 1 reply; 7+ messages in thread From: Eric Joyner @ 2026-08-15 0:00 UTC (permalink / raw) To: netdev Cc: Brett Creeley, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Nikhil P. Rao, Eric Joyner port_info is a coherent DMA buffer that the firmware keeps up to date. ionic_port_init() frees it and sets idev->port_info to NULL when the device command to initialize the port fails, and that failure path can run while the netdev is still registered: ionic_lif_deferred_work() -> ionic_lif_handle_fw_up() -> ionic_port_init() ionic_reset_done() -> ionic_setup_one() -> ionic_port_init() ionic_get_link_ext_stats() and ionic_get_link_ksettings() already test the pointer before using it, but the rest of the ethtool ops dereference it blindly, so an unprivileged "ethtool --show-fec eth0" can oops after a failed firmware recovery. Add the same check to the ops that were missing it. Fixes: c672412f6172 ("ionic: remove lifs on fw reset") Assisted-by: Claude:claude-opus-5 Signed-off-by: Eric Joyner <eric.joyner@amd.com> --- .../net/ethernet/pensando/ionic/ionic_ethtool.c | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c index c4ab4b5caa0a..0830422fe7ba 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c @@ -347,6 +347,11 @@ static int ionic_set_link_ksettings(struct net_device *netdev, if (test_bit(IONIC_LIF_F_FW_RESET, lif->state)) return -EBUSY; + if (!idev->port_info) { + netdev_err(netdev, "port_info not initialized\n"); + return -EOPNOTSUPP; + } + /* set autoneg */ if (ks->base.autoneg != idev->port_info->config.an_enable) { mutex_lock(&ionic->dev_cmd_lock); @@ -378,6 +383,11 @@ static void ionic_get_pauseparam(struct net_device *netdev, pause->autoneg = 0; + if (!lif->ionic->idev.port_info) { + netdev_err_once(netdev, "port_info not initialized\n"); + return; + } + pause_type = lif->ionic->idev.port_info->config.pause_type; if (pause_type) { pause->rx_pause = (pause_type & IONIC_PAUSE_F_RX) ? 1 : 0; @@ -396,6 +406,11 @@ static int ionic_set_pauseparam(struct net_device *netdev, if (test_bit(IONIC_LIF_F_FW_RESET, lif->state)) return -EBUSY; + if (!lif->ionic->idev.port_info) { + netdev_err(netdev, "port_info not initialized\n"); + return -EOPNOTSUPP; + } + if (pause->autoneg) return -EOPNOTSUPP; @@ -424,6 +439,11 @@ static int ionic_get_fecparam(struct net_device *netdev, { struct ionic_lif *lif = netdev_priv(netdev); + if (!lif->ionic->idev.port_info) { + netdev_err(netdev, "port_info not initialized\n"); + return -EOPNOTSUPP; + } + switch (lif->ionic->idev.port_info->config.fec_type) { case IONIC_PORT_FEC_TYPE_NONE: fec->active_fec = ETHTOOL_FEC_OFF; @@ -451,6 +471,11 @@ static int ionic_set_fecparam(struct net_device *netdev, if (test_bit(IONIC_LIF_F_FW_RESET, lif->state)) return -EBUSY; + if (!lif->ionic->idev.port_info) { + netdev_err(netdev, "port_info not initialized\n"); + return -EOPNOTSUPP; + } + if (lif->ionic->idev.port_info->config.an_enable) { netdev_err(netdev, "FEC request not allowed while autoneg is enabled\n"); return -EINVAL; @@ -1004,6 +1029,11 @@ static int ionic_get_module_eeprom_by_page(struct net_device *netdev, return -EINVAL; } + if (!idev->port_info) { + NL_SET_ERR_MSG_MOD(extack, "port_info not initialized"); + return -EOPNOTSUPP; + } + switch (page_data->page) { case 0: src = &idev->port_info->status.xcvr.sprom[page_data->offset]; -- 2.43.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH net 1/3] ionic: check for a NULL port_info in the remaining ethtool ops 2026-08-15 0:00 ` [PATCH net 1/3] ionic: check for a NULL port_info in the remaining ethtool ops Eric Joyner @ 2026-08-15 22:39 ` Vadim Fedorenko 0 siblings, 0 replies; 7+ messages in thread From: Vadim Fedorenko @ 2026-08-15 22:39 UTC (permalink / raw) To: Eric Joyner, netdev Cc: Brett Creeley, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Nikhil P. Rao On 15/08/2026 01:00, Eric Joyner wrote: > port_info is a coherent DMA buffer that the firmware keeps up to date. > ionic_port_init() frees it and sets idev->port_info to NULL when the > device command to initialize the port fails, and that failure path can > run while the netdev is still registered: > > ionic_lif_deferred_work() > -> ionic_lif_handle_fw_up() > -> ionic_port_init() > > ionic_reset_done() > -> ionic_setup_one() > -> ionic_port_init() > > ionic_get_link_ext_stats() and ionic_get_link_ksettings() already test > the pointer before using it, but the rest of the ethtool ops dereference > it blindly, so an unprivileged "ethtool --show-fec eth0" can oops after > a failed firmware recovery. > > Add the same check to the ops that were missing it. > > Fixes: c672412f6172 ("ionic: remove lifs on fw reset") > Assisted-by: Claude:claude-opus-5 > Signed-off-by: Eric Joyner <eric.joyner@amd.com> > --- > .../net/ethernet/pensando/ionic/ionic_ethtool.c | 30 ++++++++++++++++++++++ > 1 file changed, 30 insertions(+) Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev> ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH net 2/3] ionic: detach the netdev in the PCI reset handler 2026-08-15 0:00 [PATCH net 0/3] ionic: fix port_info lifetime problems around device reset Eric Joyner 2026-08-15 0:00 ` [PATCH net 1/3] ionic: check for a NULL port_info in the remaining ethtool ops Eric Joyner @ 2026-08-15 0:00 ` Eric Joyner 2026-08-15 22:43 ` Vadim Fedorenko 2026-08-15 0:00 ` [PATCH net 3/3] ionic: free port_info when probe fails after the port is set up Eric Joyner 2 siblings, 1 reply; 7+ messages in thread From: Eric Joyner @ 2026-08-15 0:00 UTC (permalink / raw) To: netdev Cc: Brett Creeley, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Nikhil P. Rao, Eric Joyner ionic_reset_prepare() tears down the queues, unmaps the BARs and calls ionic_dev_teardown(), but leaves the netdev attached and registered for the whole reset window. The ethtool core only refuses to call into a driver when netif_device_present() is false, so ethtool ops keep running against a device that is being dismantled underneath them, and ionic_reset_done() can free idev->port_info out from under one of them via ionic_setup_one() -> ionic_port_init(). The firmware recovery path already handles this properly: ionic_lif_handle_fw_down() detaches before tearing anything down; so do the same here. No matching netif_device_attach() is needed on the way back up, since ionic_reset_done() completes through ionic_restart_lif(), which already re-attaches once the queues are alive again. Fixes: a79b559e99be ("ionic: add FLR recovery support") Assisted-by: Claude:claude-opus-5 Signed-off-by: Eric Joyner <eric.joyner@amd.com> --- drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c index 05f19489ec5c..c15c4c705155 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c @@ -447,6 +447,7 @@ static void ionic_reset_prepare(struct pci_dev *pdev) dev_dbg(ionic->dev, "%s: device stopping\n", __func__); set_bit(IONIC_LIF_F_FW_RESET, lif->state); + netif_device_detach(lif->netdev); timer_delete_sync(&ionic->watchdog_timer); cancel_work_sync(&lif->deferred.work); -- 2.43.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH net 2/3] ionic: detach the netdev in the PCI reset handler 2026-08-15 0:00 ` [PATCH net 2/3] ionic: detach the netdev in the PCI reset handler Eric Joyner @ 2026-08-15 22:43 ` Vadim Fedorenko 0 siblings, 0 replies; 7+ messages in thread From: Vadim Fedorenko @ 2026-08-15 22:43 UTC (permalink / raw) To: Eric Joyner, netdev Cc: Brett Creeley, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Nikhil P. Rao On 15/08/2026 01:00, Eric Joyner wrote: > ionic_reset_prepare() tears down the queues, unmaps the BARs and calls > ionic_dev_teardown(), but leaves the netdev attached and registered for > the whole reset window. The ethtool core only refuses to call into a > driver when netif_device_present() is false, so ethtool ops keep running > against a device that is being dismantled underneath them, and > ionic_reset_done() can free idev->port_info out from under one of them > via ionic_setup_one() -> ionic_port_init(). > > The firmware recovery path already handles this properly: > ionic_lif_handle_fw_down() detaches before tearing anything down; so do > the same here. > > No matching netif_device_attach() is needed on the way back up, since > ionic_reset_done() completes through ionic_restart_lif(), which already > re-attaches once the queues are alive again. > > Fixes: a79b559e99be ("ionic: add FLR recovery support") > Assisted-by: Claude:claude-opus-5 > Signed-off-by: Eric Joyner <eric.joyner@amd.com> Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev> ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH net 3/3] ionic: free port_info when probe fails after the port is set up 2026-08-15 0:00 [PATCH net 0/3] ionic: fix port_info lifetime problems around device reset Eric Joyner 2026-08-15 0:00 ` [PATCH net 1/3] ionic: check for a NULL port_info in the remaining ethtool ops Eric Joyner 2026-08-15 0:00 ` [PATCH net 2/3] ionic: detach the netdev in the PCI reset handler Eric Joyner @ 2026-08-15 0:00 ` Eric Joyner 2026-08-15 22:49 ` Vadim Fedorenko 2 siblings, 1 reply; 7+ messages in thread From: Eric Joyner @ 2026-08-15 0:00 UTC (permalink / raw) To: netdev Cc: Brett Creeley, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Nikhil P. Rao, Eric Joyner ionic_probe() allocates the port_info DMA buffer via ionic_setup_one() -> ionic_port_init(). If probe then fails anywhere after that, it unwinds through err_out_pci, which never calls ionic_port_reset(); ionic_dev_teardown() and ionic_clear_pci() do not touch port_info, and so the buffer is leaked. Since ionic_remove() already frees the port_info DMA buffer with ionic_port_reset(), call that on the probe error path too. ionic_port_reset() returns early when port_info is NULL, so it is safe for the earlier gotos that land on the same label before the port was ever set up. Fixes: 04436595c435 ("ionic: Add port management commands") Assisted-by: Claude:claude-opus-5 Signed-off-by: Eric Joyner <eric.joyner@amd.com> --- drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c index c15c4c705155..2fb8795189b7 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c @@ -397,6 +397,7 @@ static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) err_out_free_irqs: ionic_bus_free_irq_vectors(ionic); err_out_pci: + ionic_port_reset(ionic); ionic_dev_teardown(ionic); ionic_clear_pci(ionic); ionic_debugfs_del_dev(ionic); -- 2.43.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH net 3/3] ionic: free port_info when probe fails after the port is set up 2026-08-15 0:00 ` [PATCH net 3/3] ionic: free port_info when probe fails after the port is set up Eric Joyner @ 2026-08-15 22:49 ` Vadim Fedorenko 0 siblings, 0 replies; 7+ messages in thread From: Vadim Fedorenko @ 2026-08-15 22:49 UTC (permalink / raw) To: Eric Joyner, netdev Cc: Brett Creeley, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Nikhil P. Rao On 15/08/2026 01:00, Eric Joyner wrote: > ionic_probe() allocates the port_info DMA buffer via ionic_setup_one() > -> ionic_port_init(). If probe then fails anywhere after that, it > unwinds through err_out_pci, which never calls ionic_port_reset(); > ionic_dev_teardown() and ionic_clear_pci() do not touch port_info, and > so the buffer is leaked. > > Since ionic_remove() already frees the port_info DMA buffer with > ionic_port_reset(), call that on the probe error path too. > ionic_port_reset() returns early when port_info is NULL, so it is safe > for the earlier gotos that land on the same label before the port was > ever set up. > > Fixes: 04436595c435 ("ionic: Add port management commands") > Assisted-by: Claude:claude-opus-5 > Signed-off-by: Eric Joyner <eric.joyner@amd.com> > --- > drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c > index c15c4c705155..2fb8795189b7 100644 > --- a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c > +++ b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c > @@ -397,6 +397,7 @@ static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) > err_out_free_irqs: > ionic_bus_free_irq_vectors(ionic); > err_out_pci: > + ionic_port_reset(ionic); > ionic_dev_teardown(ionic); > ionic_clear_pci(ionic); > ionic_debugfs_del_dev(ionic); > Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev> ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-08-15 22:49 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-08-15 0:00 [PATCH net 0/3] ionic: fix port_info lifetime problems around device reset Eric Joyner 2026-08-15 0:00 ` [PATCH net 1/3] ionic: check for a NULL port_info in the remaining ethtool ops Eric Joyner 2026-08-15 22:39 ` Vadim Fedorenko 2026-08-15 0:00 ` [PATCH net 2/3] ionic: detach the netdev in the PCI reset handler Eric Joyner 2026-08-15 22:43 ` Vadim Fedorenko 2026-08-15 0:00 ` [PATCH net 3/3] ionic: free port_info when probe fails after the port is set up Eric Joyner 2026-08-15 22:49 ` Vadim Fedorenko
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.