From: Selvin Xavier <selvin.xavier@broadcom.com>
To: leon@kernel.org, jgg@ziepe.ca
Cc: linux-rdma@vger.kernel.org, andrew.gospodarek@broadcom.com,
kalesh-anakkur.purayil@broadcom.com,
Selvin Xavier <selvin.xavier@broadcom.com>
Subject: [PATCH for-rc 5/8] RDMA/bnxt_re: Fix rdev lifetime races in suspend/resume/shutdown
Date: Sun, 6 Sep 2026 16:06:57 -0700 [thread overview]
Message-ID: <20260906230700.12233-6-selvin.xavier@broadcom.com> (raw)
In-Reply-To: <20260906230700.12233-1-selvin.xavier@broadcom.com>
en_info->rdev is read by unlocked L2 ULP callbacks
(bnxt_re_stop_irq/start_irq/async_notifier), which rely on rdev
being cleared before it is freed, not after. bnxt_re_add_device()
cleared it too late on a bnxt_re_dev_init() failure and
bnxt_re_resume() didn't check the return value, risking a
use-after-free/NULL deref. bnxt_re_suspend() froze and freed rdev
before clearing en_info->rdev, opening the same UAF window.
bnxt_re_shutdown() took no lock, never checked rdev for NULL, never
cleared en_info->rdev, and never freed rdev at all.
Fix the ordering in bnxt_re_add_device()/bnxt_re_suspend(), add the
missing return-value check in bnxt_re_resume(), and rewrite
bnxt_re_shutdown() to take the lock, check for NULL, and reuse
bnxt_re_remove_device() with the same clear-before-free ordering.
Fixes: dee3da3422d5 ("RDMA/bnxt_re: Change aux driver data to en_info to hold more information")
Fixes: cc5b9b48d447 ("RDMA/bnxt_re: Recover the device when FW error is detected")
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
drivers/infiniband/hw/bnxt_re/main.c | 32 ++++++++++++++++++++++------
1 file changed, 25 insertions(+), 7 deletions(-)
diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
index 17654a9e23fe..91c2edebdb93 100644
--- a/drivers/infiniband/hw/bnxt_re/main.c
+++ b/drivers/infiniband/hw/bnxt_re/main.c
@@ -2433,11 +2433,14 @@ static int bnxt_re_add_device(struct auxiliary_device *adev, u8 op_type)
bnxt_re_update_en_info_rdev(rdev, en_info, adev);
rc = bnxt_re_dev_init(rdev, op_type);
- if (rc)
+ if (rc) {
+ bnxt_re_update_en_info_rdev(NULL, en_info, adev);
goto re_dev_dealloc;
+ }
rc = bnxt_re_ib_init(rdev);
if (rc) {
+ bnxt_re_update_en_info_rdev(NULL, en_info, adev);
pr_err("Failed to register with IB: %s",
aux_priv->aux_dev.name);
goto re_dev_uninit;
@@ -2448,7 +2451,6 @@ static int bnxt_re_add_device(struct auxiliary_device *adev, u8 op_type)
return 0;
re_dev_uninit:
- bnxt_re_update_en_info_rdev(NULL, en_info, adev);
bnxt_re_dev_uninit(rdev, BNXT_RE_COMPLETE_REMOVE);
re_dev_dealloc:
ib_dealloc_device(&rdev->ibdev);
@@ -2517,9 +2519,13 @@ static int bnxt_re_suspend(struct auxiliary_device *adev, pm_message_t state)
struct bnxt_en_dev *en_dev;
struct bnxt_re_dev *rdev;
+ mutex_lock(&bnxt_re_mutex);
rdev = en_info->rdev;
+ if (!rdev) {
+ mutex_unlock(&bnxt_re_mutex);
+ return 0;
+ }
en_dev = en_info->en_dev;
- mutex_lock(&bnxt_re_mutex);
ibdev_info(&rdev->ibdev, "Handle device suspend call");
/* Check the current device state from bnxt_en_dev and move the
@@ -2539,8 +2545,9 @@ static int bnxt_re_suspend(struct auxiliary_device *adev, pm_message_t state)
ibdev_info(&rdev->ibdev, "%s: L2 driver notified to stop en_state 0x%lx",
__func__, en_dev->en_state);
- bnxt_re_remove_device(rdev, BNXT_RE_PRE_RECOVERY_REMOVE, adev);
+
bnxt_re_update_en_info_rdev(NULL, en_info, adev);
+ bnxt_re_remove_device(rdev, BNXT_RE_PRE_RECOVERY_REMOVE, adev);
mutex_unlock(&bnxt_re_mutex);
return 0;
@@ -2550,9 +2557,14 @@ static int bnxt_re_resume(struct auxiliary_device *adev)
{
struct bnxt_re_en_dev_info *en_info = auxiliary_get_drvdata(adev);
struct bnxt_re_dev *rdev;
+ int rc;
mutex_lock(&bnxt_re_mutex);
- bnxt_re_add_device(adev, BNXT_RE_POST_RECOVERY_INIT);
+ rc = bnxt_re_add_device(adev, BNXT_RE_POST_RECOVERY_INIT);
+ if (rc) {
+ mutex_unlock(&bnxt_re_mutex);
+ return rc;
+ }
rdev = en_info->rdev;
ibdev_info(&rdev->ibdev, "Device resume completed");
mutex_unlock(&bnxt_re_mutex);
@@ -2565,9 +2577,15 @@ static void bnxt_re_shutdown(struct auxiliary_device *adev)
struct bnxt_re_en_dev_info *en_info = auxiliary_get_drvdata(adev);
struct bnxt_re_dev *rdev;
+ mutex_lock(&bnxt_re_mutex);
rdev = en_info->rdev;
- ib_unregister_device(&rdev->ibdev);
- bnxt_re_dev_uninit(rdev, BNXT_RE_COMPLETE_REMOVE);
+ if (!rdev)
+ goto out;
+
+ bnxt_re_update_en_info_rdev(NULL, en_info, adev);
+ bnxt_re_remove_device(rdev, BNXT_RE_COMPLETE_REMOVE, adev);
+out:
+ mutex_unlock(&bnxt_re_mutex);
}
static const struct auxiliary_device_id bnxt_re_id_table[] = {
--
2.39.3
next prev parent reply other threads:[~2026-09-06 17:46 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-06 23:06 [PATCH for-rc 0/8] RDMA/bnxt_re: Fix input validation and lifetime bugs Selvin Xavier
2026-09-06 23:06 ` [PATCH for-rc 1/8] RDMA/bnxt_re: Reject executable mappings of the DBR and toggle pages Selvin Xavier
2026-09-08 13:45 ` Leon Romanovsky
2026-09-09 4:57 ` Selvin Xavier
2026-09-09 13:29 ` Jason Gunthorpe
2026-09-10 9:26 ` Leon Romanovsky
2026-09-10 13:47 ` Jason Gunthorpe
2026-09-06 23:06 ` [PATCH for-rc 2/8] RDMA/bnxt_re: Detect wrong sge_len passed for inline Selvin Xavier
2026-09-06 23:06 ` [PATCH for-rc 3/8] RDMA/bnxt_re: Validate num_sge in bnxt_re_post_srq_recv() Selvin Xavier
2026-09-06 23:06 ` [PATCH for-rc 4/8] RDMA/bnxt_re: Validate SRQ max_sge at create time Selvin Xavier
2026-09-06 23:06 ` Selvin Xavier [this message]
2026-09-06 23:06 ` [PATCH for-rc 6/8] RDMA/bnxt_re: Fix the PD and DPI table size Selvin Xavier
2026-09-06 23:06 ` [PATCH for-rc 7/8] RDMA/bnxt_re: Use bnxt_ext_stats_supported for counter count selection Selvin Xavier
2026-09-06 23:07 ` [PATCH for-rc 8/8] RDMA/bnxt_re: Check is_in_used before trusting RCFW completion Selvin Xavier
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=20260906230700.12233-6-selvin.xavier@broadcom.com \
--to=selvin.xavier@broadcom.com \
--cc=andrew.gospodarek@broadcom.com \
--cc=jgg@ziepe.ca \
--cc=kalesh-anakkur.purayil@broadcom.com \
--cc=leon@kernel.org \
--cc=linux-rdma@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.