The driver was not passing the HWRM command response to management
apps when the firmware failed the command, which is not what apps
expect. Copy the response out whenever firmware populated one
(resp_len != 0), regardless of the command's overall return code, and
stop bailing out of the mgmt ioctl path early on a failed passthrough
so DMA'd indirect data and the response still get copied to
userspace.
Details
Details
Diff Detail
Diff Detail
- Repository
- rG FreeBSD src repository
- Lint
Lint Not Applicable - Unit
Tests Not Applicable
Event Timeline
Comment Actions
AI scan fixes:
- Copying "regardless of the command's overall return code" also covers ETIMEDOUT, but _hwrm_send_message() can return that without ever confirming firmware's valid-byte marker for *this* specific command, in which case output->resp_len and the rest of the shared hwrm_cmd_resp DMA buffer may still hold a previous, unrelated command's response - which this change would then copy out to the ioctl caller under the current command's identity. Skip the copy entirely on ETIMEDOUT; every other return path (success, or a firmware-reported error via bnxt_hwrm_err_map()) only happens after that valid-byte wait succeeds. Also clamp the copy length to min(caller's resp_len, output->resp_len, PAGE_SIZE) - the caller- supplied resp_len was used unclamped, and PAGE_SIZE is hwrm_cmd_resp's actual allocation size.
- bnxt_mgmt_process_hwrm() validates len_req/len_resp from its first copyin (msg_temp) and sizes req/resp from those validated values, but a second copyin (msg2, only when num_dma_indications != 0) re-reads the same header fields from userspace without re-validating them, then passes *those* lengths to bnxt_hwrm_passthrough() as the memcpy/copyout size - a userspace-controlled heap overflow and out-of-bounds read whenever the two copies disagree. Require msg2's len_req/len_resp to match the already-validated msg_temp values.