Skip to content

Commit 1cb8553

Browse files
Ryuwang3Paolo Abeni
authored andcommitted
bnxt_en: Handle partially initialized auxiliary devices
bnxt_aux_devices_init() calls auxiliary_device_init() before all fields used by bnxt_aux_dev_release() are initialized. After auxiliary_device_init() succeeds, later errors must unwind with auxiliary_device_uninit(), which invokes the release callback. The release callback assumes that aux_priv->id, aux_priv->edev, edev->net and edev->ulp_tbl are all populated. If allocation fails after auxiliary_device_init(), the release path can otherwise dereference or clear partially initialized state. Allocate and attach the bnxt_en_dev and ULP table before calling auxiliary_device_init(), so the release callback only sees a fully initialized auxiliary private object. If auxiliary_device_init() itself fails, free those allocations directly because device_initialize() has not run and the release callback will not be invoked. This issue was found by a static analysis checker and confirmed by manual source review. Fixes: 194fad5 ("bnxt_en: Refactor bnxt_rdma_aux_device_init/uninit functions") Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com> Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com> Link: https://patch.msgid.link/20260711163716.3996929-1-ruoyuw560@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent e0b5252 commit 1cb8553

1 file changed

Lines changed: 20 additions & 19 deletions

File tree

drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -566,44 +566,45 @@ void bnxt_aux_devices_init(struct bnxt *bp)
566566
if (!aux_priv)
567567
goto next_auxdev;
568568

569+
edev = kzalloc_obj(*edev);
570+
if (!edev)
571+
goto aux_priv_free;
572+
aux_priv->edev = edev;
573+
bnxt_set_edev_info(edev, bp);
574+
575+
ulp = kzalloc_obj(*ulp);
576+
if (!ulp)
577+
goto edev_free;
578+
edev->ulp_tbl = ulp;
579+
aux_priv->id = idx;
580+
569581
aux_dev = &aux_priv->aux_dev;
570582
aux_dev->id = bp->auxdev_id;
571583
aux_dev->name = bnxt_aux_devices[idx].name;
572584
aux_dev->dev.parent = &bp->pdev->dev;
573585
aux_dev->dev.release = bnxt_aux_dev_release;
574586

575587
rc = auxiliary_device_init(aux_dev);
576-
if (rc) {
577-
kfree(aux_priv);
578-
goto next_auxdev;
579-
}
588+
if (rc)
589+
goto ulp_free;
580590
bp->aux_priv[idx] = aux_priv;
581591

582592
/* From this point, all cleanup will happen via the .release
583593
* callback & any error unwinding will need to include a call
584594
* to auxiliary_device_uninit.
585595
*/
586-
edev = kzalloc_obj(*edev);
587-
if (!edev)
588-
goto aux_dev_uninit;
589-
590-
aux_priv->edev = edev;
591-
bnxt_set_edev_info(edev, bp);
592-
593-
ulp = kzalloc_obj(*ulp);
594-
if (!ulp)
595-
goto aux_dev_uninit;
596-
597-
edev->ulp_tbl = ulp;
598596
bp->edev[idx] = edev;
599597
if (idx == BNXT_AUXDEV_RDMA)
600598
bp->ulp_num_msix_want = bnxt_set_dflt_ulp_msix(bp);
601-
aux_priv->id = idx;
602599
bnxt_auxdev_set_state(bp, idx, BNXT_ADEV_STATE_INIT);
603600

604601
continue;
605-
aux_dev_uninit:
606-
auxiliary_device_uninit(aux_dev);
602+
ulp_free:
603+
kfree(ulp);
604+
edev_free:
605+
kfree(edev);
606+
aux_priv_free:
607+
kfree(aux_priv);
607608
next_auxdev:
608609
if (idx == BNXT_AUXDEV_RDMA)
609610
bp->flags &= ~BNXT_FLAG_ROCE_CAP;

0 commit comments

Comments
 (0)