Date: Tue, 28 Sep 2021 17:30:10 GMT From: Kevin Bowling <kbowling@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 5b4cfd3f1315 - stable/12 - iflib: Free resources in a consistent order during detach Message-ID: <202109281730.18SHUAAh079480@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/12 has been updated by kbowling (ports committer): URL: https://cgit.FreeBSD.org/src/commit/?id=5b4cfd3f1315856029256a9847d78d3b1b717fb0 commit 5b4cfd3f1315856029256a9847d78d3b1b717fb0 Author: Sai Rajesh Tallamraju <stallamr@netapp.com> AuthorDate: 2021-02-01 16:13:00 +0000 Commit: Kevin Bowling <kbowling@FreeBSD.org> CommitDate: 2021-09-28 17:21:52 +0000 iflib: Free resources in a consistent order during detach Memory and PCI resources are freed with no particular order. This could cause use-after-frees when detaching following a failed attach. For instance, iflib_tx_structures_free() frees ctx->ifc_txqs[] but iflib_tqg_detach() attempts to access this array. Similarly, adapter queues gets freed by IFDI_QUEUES_FREE() but IFDI_DETACH() attempts to access adapter queues to free PCI resources. MFC after: 2 weeks Sponsored by: NetApp, Inc. Differential Revision: https://reviews.freebsd.org/D27634 (cherry picked from commit 38bfc6dee33bedb290e1ea2540f97a86fe3caee0) --- sys/dev/e1000/if_em.c | 19 ++++++------------- sys/dev/ixl/if_ixl.c | 2 +- sys/net/iflib.c | 22 +++++++++++++--------- 3 files changed, 20 insertions(+), 23 deletions(-) diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index a571450a463e..7babe51c8c02 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -1127,10 +1127,11 @@ em_if_attach_post(if_ctx_t ctx) struct adapter *adapter = iflib_get_softc(ctx); struct e1000_hw *hw = &adapter->hw; int error = 0; - + /* Setup OS specific network interface */ error = em_setup_interface(ctx); if (error != 0) { + device_printf(adapter->dev, "Interface setup failed: %d\n", error); goto err_late; } @@ -1148,14 +1149,10 @@ em_if_attach_post(if_ctx_t ctx) INIT_DEBUGOUT("em_if_attach_post: end"); - return (error); + return (0); err_late: - em_release_hw_control(adapter); - em_free_pci_resources(ctx); - em_if_queues_free(ctx); - free(adapter->mta, M_DEVBUF); - + /* upon attach_post() error, iflib calls _if_detach() to free resources. */ return (error); } @@ -1180,6 +1177,8 @@ em_if_detach(if_ctx_t ctx) em_release_manageability(adapter); em_release_hw_control(adapter); em_free_pci_resources(ctx); + free(adapter->mta, M_DEVBUF); + adapter->mta = NULL; return (0); } @@ -3012,12 +3011,6 @@ em_if_queues_free(if_ctx_t ctx) free(adapter->rx_queues, M_DEVBUF); adapter->rx_queues = NULL; } - - em_release_hw_control(adapter); - - if (adapter->mta != NULL) { - free(adapter->mta, M_DEVBUF); - } } /********************************************************************* diff --git a/sys/dev/ixl/if_ixl.c b/sys/dev/ixl/if_ixl.c index 8741eb06ac18..45ac55ec2da8 100644 --- a/sys/dev/ixl/if_ixl.c +++ b/sys/dev/ixl/if_ixl.c @@ -1275,7 +1275,7 @@ ixl_if_queues_free(if_ctx_t ctx) struct ixl_pf *pf = iflib_get_softc(ctx); struct ixl_vsi *vsi = &pf->vsi; - if (!vsi->enable_head_writeback) { + if (vsi->tx_queues != NULL && !vsi->enable_head_writeback) { struct ixl_tx_queue *que; int i = 0; diff --git a/sys/net/iflib.c b/sys/net/iflib.c index f8d4c120b3ec..2d53b1ef8229 100644 --- a/sys/net/iflib.c +++ b/sys/net/iflib.c @@ -5157,7 +5157,7 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct device_printf(dev, "Cannot use iflib with only 1 MSI-X interrupt!\n"); err = ENODEV; - goto fail_intr_free; + goto fail_queues; } ether_ifattach(ctx->ifc_ifp, ctx->ifc_mac); @@ -5192,13 +5192,14 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct fail_detach: ether_ifdetach(ctx->ifc_ifp); -fail_intr_free: - iflib_free_intr_mem(ctx); fail_queues: + iflib_tqg_detach(ctx); iflib_tx_structures_free(ctx); iflib_rx_structures_free(ctx); - iflib_tqg_detach(ctx); IFDI_DETACH(ctx); + IFDI_QUEUES_FREE(ctx); +fail_intr_free: + iflib_free_intr_mem(ctx); fail_unlock: CTX_UNLOCK(ctx); iflib_deregister(ctx); @@ -5397,11 +5398,12 @@ iflib_pseudo_register(device_t dev, if_shared_ctx_t sctx, if_ctx_t *ctxp, fail_detach: ether_ifdetach(ctx->ifc_ifp); fail_queues: + iflib_tqg_detach(ctx); iflib_tx_structures_free(ctx); iflib_rx_structures_free(ctx); - iflib_tqg_detach(ctx); fail_iflib_detach: IFDI_DETACH(ctx); + IFDI_QUEUES_FREE(ctx); fail_unlock: CTX_UNLOCK(ctx); iflib_deregister(ctx); @@ -5431,6 +5433,8 @@ iflib_pseudo_deregister(if_ctx_t ctx) iflib_tqg_detach(ctx); iflib_tx_structures_free(ctx); iflib_rx_structures_free(ctx); + IFDI_DETACH(ctx); + IFDI_QUEUES_FREE(ctx); iflib_deregister(ctx); @@ -5490,8 +5494,12 @@ iflib_device_deregister(if_ctx_t ctx) led_destroy(ctx->ifc_led_dev); iflib_tqg_detach(ctx); + iflib_tx_structures_free(ctx); + iflib_rx_structures_free(ctx); + CTX_LOCK(ctx); IFDI_DETACH(ctx); + IFDI_QUEUES_FREE(ctx); CTX_UNLOCK(ctx); /* ether_ifdetach calls if_qflush - lock must be destroy afterwards*/ @@ -5499,9 +5507,6 @@ iflib_device_deregister(if_ctx_t ctx) bus_generic_detach(dev); - iflib_tx_structures_free(ctx); - iflib_rx_structures_free(ctx); - iflib_deregister(ctx); device_set_softc(ctx->ifc_dev, NULL); @@ -6084,7 +6089,6 @@ iflib_tx_structures_free(if_ctx_t ctx) } free(ctx->ifc_txqs, M_IFLIB); ctx->ifc_txqs = NULL; - IFDI_QUEUES_FREE(ctx); } /*********************************************************************
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202109281730.18SHUAAh079480>