]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ixgbe: fix memory leaks in the ixgbe_recovery_probe() path
authorKohei Enju <enjuk@amazon.com>
Thu, 11 Dec 2025 09:15:31 +0000 (18:15 +0900)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Tue, 27 Jan 2026 21:50:09 +0000 (13:50 -0800)
When ixgbe_recovery_probe() is invoked and this function fails,
allocated resources in advance are not completely freed, because
ixgbe_probe() returns ixgbe_recovery_probe() directly and
ixgbe_recovery_probe() only frees partial resources, resulting in memory
leaks including:
- adapter->io_addr
- adapter->jump_tables[0]
- adapter->mac_table
- adapter->rss_key
- adapter->af_xdp_zc_qps

The leaked MMIO region can be observed in /proc/vmallocinfo, and the
remaining leaks are reported by kmemleak.

Don't return ixgbe_recovery_probe() directly, and instead let
ixgbe_probe() to clean up resources on failures.

Fixes: 29cb3b8d95c7 ("ixgbe: add E610 implementation of FW recovery mode")
Signed-off-by: Kohei Enju <enjuk@amazon.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c

index 034618e79169e4e0f79d7fa8c2f0d5000d7640e9..a69b5a8a91cb23652494d412e6d2689cfb792d3b 100644 (file)
@@ -11468,14 +11468,12 @@ static void ixgbe_set_fw_version(struct ixgbe_adapter *adapter)
  */
 static int ixgbe_recovery_probe(struct ixgbe_adapter *adapter)
 {
-       struct net_device *netdev = adapter->netdev;
        struct pci_dev *pdev = adapter->pdev;
        struct ixgbe_hw *hw = &adapter->hw;
-       bool disable_dev;
        int err = -EIO;
 
        if (hw->mac.type != ixgbe_mac_e610)
-               goto clean_up_probe;
+               return err;
 
        ixgbe_get_hw_control(adapter);
        mutex_init(&hw->aci.lock);
@@ -11507,13 +11505,6 @@ static int ixgbe_recovery_probe(struct ixgbe_adapter *adapter)
 shutdown_aci:
        mutex_destroy(&adapter->hw.aci.lock);
        ixgbe_release_hw_control(adapter);
-clean_up_probe:
-       disable_dev = !test_and_set_bit(__IXGBE_DISABLED, &adapter->state);
-       free_netdev(netdev);
-       devlink_free(adapter->devlink);
-       pci_release_mem_regions(pdev);
-       if (disable_dev)
-               pci_disable_device(pdev);
        return err;
 }
 
@@ -11655,8 +11646,13 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (err)
                goto err_sw_init;
 
-       if (ixgbe_check_fw_error(adapter))
-               return ixgbe_recovery_probe(adapter);
+       if (ixgbe_check_fw_error(adapter)) {
+               err = ixgbe_recovery_probe(adapter);
+               if (err)
+                       goto err_sw_init;
+
+               return 0;
+       }
 
        if (adapter->hw.mac.type == ixgbe_mac_e610) {
                err = ixgbe_get_caps(&adapter->hw);