drivers/infiniband/hw/mana/main.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-)
As part of MANA hardening for CVM, clamp hardware-reported adapter
capability values from the MANA_IB_GET_ADAPTER_CAP response before
they are used by the IB subsystem.
The response fields (max_qp_count, max_cq_count, max_mr_count,
max_pd_count, max_inbound_read_limit, max_outbound_read_limit,
max_qp_wr, max_send_sge_count, max_recv_sge_count) are u32 but are
assigned to signed int members in struct ib_device_attr. If hardware
returns a value exceeding INT_MAX, the implicit u32-to-int conversion
produces a negative value, which can cause incorrect behavior in the
IB core and userspace applications.
Clamp these fields to INT_MAX in mana_ib_gd_query_adapter_caps() so
all downstream consumers receive safe values.
Additionally, fix an integer overflow in mana_ib_query_device() where
max_res_rd_atom is computed as max_qp_rd_atom * max_qp. Both operands
are int and the multiplication can overflow. Widen to s64 before
multiplying and clamp the result to INT_MAX.
Signed-off-by: Erni Sri Satya Vennela <ernis@linux.microsoft.com>
---
Changes in v2:
* Update patch title.
---
drivers/infiniband/hw/mana/main.c | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/drivers/infiniband/hw/mana/main.c b/drivers/infiniband/hw/mana/main.c
index 8d99cd00f002..2869660077ef 100644
--- a/drivers/infiniband/hw/mana/main.c
+++ b/drivers/infiniband/hw/mana/main.c
@@ -599,7 +599,8 @@ int mana_ib_query_device(struct ib_device *ibdev, struct ib_device_attr *props,
props->max_mr = dev->adapter_caps.max_mr_count;
props->max_pd = dev->adapter_caps.max_pd_count;
props->max_qp_rd_atom = dev->adapter_caps.max_inbound_read_limit;
- props->max_res_rd_atom = props->max_qp_rd_atom * props->max_qp;
+ props->max_res_rd_atom =
+ min_t(s64, (s64)props->max_qp_rd_atom * props->max_qp, INT_MAX);
props->max_qp_init_rd_atom = dev->adapter_caps.max_outbound_read_limit;
props->atomic_cap = IB_ATOMIC_NONE;
props->masked_atomic_cap = IB_ATOMIC_NONE;
@@ -694,20 +695,22 @@ int mana_ib_gd_query_adapter_caps(struct mana_ib_dev *dev)
caps->max_sq_id = resp.max_sq_id;
caps->max_rq_id = resp.max_rq_id;
caps->max_cq_id = resp.max_cq_id;
- caps->max_qp_count = resp.max_qp_count;
- caps->max_cq_count = resp.max_cq_count;
- caps->max_mr_count = resp.max_mr_count;
- caps->max_pd_count = resp.max_pd_count;
- caps->max_inbound_read_limit = resp.max_inbound_read_limit;
- caps->max_outbound_read_limit = resp.max_outbound_read_limit;
+ caps->max_qp_count = min_t(u32, resp.max_qp_count, INT_MAX);
+ caps->max_cq_count = min_t(u32, resp.max_cq_count, INT_MAX);
+ caps->max_mr_count = min_t(u32, resp.max_mr_count, INT_MAX);
+ caps->max_pd_count = min_t(u32, resp.max_pd_count, INT_MAX);
+ caps->max_inbound_read_limit = min_t(u32, resp.max_inbound_read_limit,
+ INT_MAX);
+ caps->max_outbound_read_limit = min_t(u32, resp.max_outbound_read_limit,
+ INT_MAX);
caps->mw_count = resp.mw_count;
caps->max_srq_count = resp.max_srq_count;
caps->max_qp_wr = min_t(u32,
resp.max_requester_sq_size / GDMA_MAX_SQE_SIZE,
resp.max_requester_rq_size / GDMA_MAX_RQE_SIZE);
caps->max_inline_data_size = resp.max_inline_data_size;
- caps->max_send_sge_count = resp.max_send_sge_count;
- caps->max_recv_sge_count = resp.max_recv_sge_count;
+ caps->max_send_sge_count = min_t(u32, resp.max_send_sge_count, INT_MAX);
+ caps->max_recv_sge_count = min_t(u32, resp.max_recv_sge_count, INT_MAX);
caps->feature_flags = resp.feature_flags;
caps->page_size_cap = PAGE_SZ_BM;
--
2.34.1
On Thu, Mar 12, 2026 at 11:16:41AM -0700, Erni Sri Satya Vennela wrote: > As part of MANA hardening for CVM, clamp hardware-reported adapter > capability values from the MANA_IB_GET_ADAPTER_CAP response before > they are used by the IB subsystem. > > The response fields (max_qp_count, max_cq_count, max_mr_count, > max_pd_count, max_inbound_read_limit, max_outbound_read_limit, > max_qp_wr, max_send_sge_count, max_recv_sge_count) are u32 but are > assigned to signed int members in struct ib_device_attr. If hardware > returns a value exceeding INT_MAX, the implicit u32-to-int conversion > produces a negative value, which can cause incorrect behavior in the > IB core and userspace applications. This sentence does not make sense in the context of the Linux kernel. The fundamental assumption is that the underlying hardware behaves correctly, and driver code should not attempt to guard against purely hypothetical failures. The kernel only implements such self‑protection when there is a documented hardware issue accompanied by official errata. Thanks
On Thu, Mar 12, 2026 at 11:16:41AM -0700, Erni Sri Satya Vennela wrote: > The response fields (max_qp_count, max_cq_count, max_mr_count, > max_pd_count, max_inbound_read_limit, max_outbound_read_limit, > max_qp_wr, max_send_sge_count, max_recv_sge_count) are u32 but are > assigned to signed int members in struct ib_device_attr. There is no reason they should be signed, you should just fix the type. I'm also not convinced clamping to such a high value has any value whatsoever, as it probably still triggers maths overflows elsewhere. I think you should clamp to reasonable limits for your device if you want to do this. Jason
© 2016 - 2026 Red Hat, Inc.