From: Jakub Kicinski <kuba@kernel.org>
To: anthony.l.nguyen@intel.com
Cc: Jakub Kicinski <kuba@kernel.org>,
davem@davemloft.net, pabeni@redhat.com, edumazet@google.com,
andrew+netdev@lunn.ch, netdev@vger.kernel.org, doruk@0sec.ai,
michal.swiatkowski@linux.intel.com, grzegorz.nitka@intel.com,
horms@kernel.org, przemyslaw.kitszel@intel.com,
stable@vger.kernel.org, aleksandr.loktionov@intel.com,
marcin.szycik@linux.intel.com
Subject: Re: [PATCH net 09/10] i40e: fix netdev leak in i40e_vsi_setup() error paths
Date: Thu, 6 Aug 2026 10:20:51 -0700 [thread overview]
Message-ID: <20260806172051.2936459-1-kuba@kernel.org> (raw)
In-Reply-To: <20260804222205.1580328-10-anthony.l.nguyen@intel.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.
---
i40e: fix netdev leak in i40e_vsi_setup() error paths
This moves the free_netdev() call out of the netdev_registered block at
err_msix and into a new unconditional block at err_netdev, so that the
netdev allocated by i40e_config_netdev() is released when
i40e_netif_set_realnum_tx_rx_queues(), i40e_devlink_create_port() or
register_netdev() fail.
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
> index 0ac1be6289f6b..4f0f7626605ba 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
> @@ -14494,13 +14494,15 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type,
> if (vsi->netdev_registered) {
> vsi->netdev_registered = false;
> unregister_netdev(vsi->netdev);
> - free_netdev(vsi->netdev);
> - vsi->netdev = NULL;
> }
> err_dl_port:
> if (vsi->type == I40E_VSI_MAIN)
> i40e_devlink_destroy_port(pf);
> err_netdev:
> + if (vsi->netdev) {
> + free_netdev(vsi->netdev);
> + vsi->netdev = NULL;
> + }
[Severity: Medium]
On the newly covered paths the netdev was never registered, but the VSI
is already published in pf->vsi[vsi->idx] by i40e_vsi_mem_alloc(), and
i40e_config_netdev() has already run i40e_add_mac_filter() for the
unicast and broadcast addresses, which does:
drivers/net/ethernet/intel/i40e/i40e_main.c:i40e_add_filter() {
...
vsi->flags |= I40E_VSI_FLAG_FILTER_CHANGED;
set_bit(__I40E_MACVLAN_SYNC_PENDING, vsi->back->state);
...
}
The service work item then walks pf->vsi[] with no lock:
i40e_sync_filters_subtask() {
i40e_pf_for_each_vsi(pf, v, vsi) {
if ((vsi->flags & I40E_VSI_FLAG_FILTER_CHANGED) &&
!test_bit(__I40E_VSI_RELEASING, vsi->state)) {
int ret = i40e_sync_vsi_filters(vsi);
...
}
and i40e_sync_vsi_filters() dereferences the netdev:
i40e_sync_vsi_filters() {
...
if (vsi->netdev) {
changed_flags = vsi->current_netdev_flags ^ vsi->netdev->flags;
vsi->current_netdev_flags = vsi->netdev->flags;
}
...
}
Can the service task load vsi->netdev, pass the NULL test, and then
dereference it after this free_netdev()? The error path does not set
__I40E_VSI_RELEASING first, which is the ordering i40e_vsi_release()
uses before its own free_netdev(), and the vsi->netdev = NULL store
carries no lock or barrier.
This is reachable at runtime for I40E_VSI_VMDQ2 VSIs created from
debugfs, where i40e_dbg_command_write() calls
i40e_vsi_setup(pf, I40E_VSI_VMDQ2, vsi_seid, 0) while the service work
item is live. Would setting __I40E_VSI_RELEASING (or clearing
I40E_VSI_FLAG_FILTER_CHANGED / unpublishing pf->vsi[idx] under
pf->switch_mutex) before dropping the netdev close this window, mirroring
i40e_vsi_release()?
The exposure window is short, since the following i40e_vsi_clear() also
kfree()s the still-published struct i40e_vsi on these same paths, which
is a pre-existing unsynchronised teardown.
[Severity: High]
This isn't a bug introduced by this patch, but the other in-tree caller of
i40e_config_netdev() does not follow the ownership rule this hunk
codifies. In i40e_init_recovery_mode() the netdev is never released:
err = i40e_config_netdev(vsi);
if (err)
goto err_switch_setup;
err = register_netdev(vsi->netdev);
if (err)
goto err_switch_setup;
vsi->netdev_registered = true;
i40e_dbg_pf_init(pf);
err = i40e_setup_misc_vector_for_recovery_mode(pf);
if (err)
goto err_switch_setup;
If register_netdev() fails, is the net_device allocated by
alloc_etherdev_mq() inside i40e_config_netdev() leaked? i40e_probe()
does "return i40e_init_recovery_mode(pf, hw);", so i40e_remove() never
runs for the failed probe and nothing later frees it.
The case where register_netdev() succeeded and
i40e_setup_misc_vector_for_recovery_mode() then fails looks worse, since
err_switch_setup never calls unregister_netdev():
err_switch_setup:
i40e_reset_interrupt_capability(pf);
timer_shutdown_sync(&pf->service_timer);
i40e_shutdown_adminq(hw);
iounmap(hw->hw_addr);
pci_release_mem_regions(pf->pdev);
pci_disable_device(pf->pdev);
i40e_free_pf(pf);
return err;
i40e_free_pf() is devlink_free() on the devlink whose priv is the struct
i40e_pf, so the netdev stays registered in the netns while its
netdev_priv()->vsi->back has been freed and hw->hw_addr has been
iounmapped. Can a later "ip link set <dev> up" on the leftover interface
reach i40e_open() and touch the freed pf and the unmapped register
window? The debugfs directory created by i40e_dbg_pf_init(pf) is left in
place pointing at the freed pf as well.
Would it make sense to fix that call site in the same series, so both
users of i40e_config_netdev() release the netdev consistently?
next prev parent reply other threads:[~2026-08-06 17:20 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-04 22:21 [PATCH net 00/10][pull request] Intel Wired LAN Driver Updates 2026-08-04 (iavf, i40e, ice, igc) Tony Nguyen
2026-08-04 22:21 ` [PATCH net 01/10] iavf: return EBUSY if reset in progress or not ready during MAC change Tony Nguyen
2026-08-06 17:20 ` Jakub Kicinski
2026-08-12 6:56 ` Jose Ignacio Tornos Martinez
2026-08-04 22:21 ` [PATCH net 02/10] i40e: skip unnecessary VF reset when setting trust Tony Nguyen
2026-08-06 17:20 ` Jakub Kicinski
2026-08-12 6:59 ` Jose Ignacio Tornos Martinez
2026-08-04 22:21 ` [PATCH net 03/10] iavf: send MAC change request synchronously Tony Nguyen
2026-08-06 17:20 ` Jakub Kicinski
2026-08-12 7:02 ` Jose Ignacio Tornos Martinez
2026-08-04 22:21 ` [PATCH net 04/10] ice: skip unnecessary VF reset when setting trust Tony Nguyen
2026-08-06 17:20 ` Jakub Kicinski
2026-08-12 7:05 ` Jose Ignacio Tornos Martinez
2026-08-04 22:21 ` [PATCH net 05/10] ice: move ice_vsi_realloc_stat_arrays() up Tony Nguyen
2026-08-04 22:21 ` [PATCH net 06/10] ice: fix stats array overflow via proper realloc Tony Nguyen
2026-08-06 17:20 ` Jakub Kicinski
2026-08-04 22:22 ` [PATCH net 07/10] ice: eswitch: fix use-after-free of metadata_dst in repr release Tony Nguyen
2026-08-06 17:20 ` Jakub Kicinski
2026-08-04 22:22 ` [PATCH net 08/10] i40e: fix memcmp of pointer in i40e_hw_set_dcb_config() Tony Nguyen
2026-08-06 17:20 ` Jakub Kicinski
2026-08-04 22:22 ` [PATCH net 09/10] i40e: fix netdev leak in i40e_vsi_setup() error paths Tony Nguyen
2026-08-06 17:20 ` Jakub Kicinski [this message]
2026-08-04 22:22 ` [PATCH net 10/10] igc: fix netdev not re-attached after resume if interface is down Tony Nguyen
2026-08-06 17:19 ` [PATCH net 00/10][pull request] Intel Wired LAN Driver Updates 2026-08-04 (iavf, i40e, ice, igc) Jakub Kicinski
2026-08-06 17:30 ` patchwork-bot+netdevbpf
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=20260806172051.2936459-1-kuba@kernel.org \
--to=kuba@kernel.org \
--cc=aleksandr.loktionov@intel.com \
--cc=andrew+netdev@lunn.ch \
--cc=anthony.l.nguyen@intel.com \
--cc=davem@davemloft.net \
--cc=doruk@0sec.ai \
--cc=edumazet@google.com \
--cc=grzegorz.nitka@intel.com \
--cc=horms@kernel.org \
--cc=marcin.szycik@linux.intel.com \
--cc=michal.swiatkowski@linux.intel.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=przemyslaw.kitszel@intel.com \
--cc=stable@vger.kernel.org \
/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.