Thread (7 messages) flat view 7 messages, 2 authors, 1d ago
WARM1d

[PATCH net 1/3] ionic: check for a NULL port_info in the remaining ethtool ops

From: Eric Joyner <hidden>
Date: 2026-08-15 00:00:48
Subsystem: networking drivers, pensando ethernet drivers, the rest · Maintainers: Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Brett Creeley, Linus Torvalds

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 <redacted>
---
 .../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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help