From: Joseph Wong <[email protected]>
bnxt_handle_fwd_req() computed vf_id from an unvalidated,
firmware-controlled source_id and used it to index
bp->pf->vf_info[] before checking that the ID falls within the
active VF range. An out-of-range VF ID could index past
vf_info[] and cause memory corruption.
Move the range check ahead of the vf_id computation and the
vf_info[] lookup. Guard the later fwd_cmd/req_len usage on the
reject path, since they are no longer set when the request is
rejected early. Also guard bnxt_hwrm_reject_fwd_resp()'s memcpy()
against a NULL encaped pointer for the same reason.
Fixes: f2a768d4d186 ("net/bnxt: add completion ring")
Cc: [email protected]
Signed-off-by: Joseph Wong <[email protected]>
Signed-off-by: Mohammad Shuab Siddique <[email protected]>
---
drivers/net/bnxt/bnxt_cpr.c | 25 ++++++++++++++-----------
drivers/net/bnxt/bnxt_hwrm.c | 3 ++-
2 files changed, 16 insertions(+), 12 deletions(-)
diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c
index 5c255de59e..ac731ea72f 100644
--- a/drivers/net/bnxt/bnxt_cpr.c
+++ b/drivers/net/bnxt/bnxt_cpr.c
@@ -375,16 +375,6 @@ void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base
*cmpl)
/* Qualify the fwd request */
fw_vf_id = rte_le_to_cpu_16(fwd_cmpl->source_id);
- vf_id = fw_vf_id - bp->pf->first_vf_id;
-
- req_len = (rte_le_to_cpu_16(fwd_cmpl->req_len_type) &
- HWRM_FWD_REQ_CMPL_REQ_LEN_MASK) >>
- HWRM_FWD_REQ_CMPL_REQ_LEN_SFT;
- if (req_len > sizeof(fwreq->encap_request))
- req_len = sizeof(fwreq->encap_request);
-
- /* Locate VF's forwarded command */
- fwd_cmd = (struct input *)bp->pf->vf_info[vf_id].req_buf;
if (fw_vf_id < bp->pf->first_vf_id ||
fw_vf_id >= bp->pf->first_vf_id + bp->pf->active_vfs) {
@@ -393,9 +383,22 @@ void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base
*cmpl)
fw_vf_id, bp->pf->first_vf_id,
(bp->pf->first_vf_id) + bp->pf->active_vfs - 1,
bp->pf->first_vf_id, bp->pf->active_vfs);
+ fwd_cmd = NULL;
+ req_len = 0;
goto reject;
}
+ vf_id = fw_vf_id - bp->pf->first_vf_id;
+
+ req_len = (rte_le_to_cpu_16(fwd_cmpl->req_len_type) &
+ HWRM_FWD_REQ_CMPL_REQ_LEN_MASK) >>
+ HWRM_FWD_REQ_CMPL_REQ_LEN_SFT;
+ if (req_len > sizeof(fwreq->encap_request))
+ req_len = sizeof(fwreq->encap_request);
+
+ /* Locate VF's forwarded command */
+ fwd_cmd = (struct input *)bp->pf->vf_info[vf_id].req_buf;
+
if (bnxt_rcv_msg_from_vf(bp, vf_id, fwd_cmd)) {
/*
* In older firmware versions, the MAC had to be all zeros for
@@ -495,7 +498,7 @@ void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base
*cmpl)
PMD_DRV_LOG_LINE(ERR,
"Failed to send REJECT req VF 0x%x, type 0x%x.",
fw_vf_id - bp->pf->first_vf_id,
- rte_le_to_cpu_16(fwd_cmd->req_type));
+ fwd_cmd ? rte_le_to_cpu_16(fwd_cmd->req_type) : 0xFFFF);
}
return;
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 1615b36aae..aa8152eaa0 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -5520,7 +5520,8 @@ int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t
target_id,
HWRM_PREP(&req, HWRM_REJECT_FWD_RESP, BNXT_USE_CHIMP_MB);
req.encap_resp_target_id = rte_cpu_to_le_16(target_id);
- memcpy(req.encap_request, encaped, ec_size);
+ if (encaped)
+ memcpy(req.encap_request, encaped, ec_size);
rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
--
2.47.3