aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Morgenstein <jackm@dev.mellanox.co.il>2007-10-18 11:36:43 -0400
committerRoland Dreier <rolandd@cisco.com>2007-10-18 12:27:26 -0400
commit839041329fd3410e07d614f81e75bb43367d8f89 (patch)
treeae9b3f9dd42bb9f4652637d6700b685e2f41e961
parentfd312561adcc90e924f35d3032d5493aeb4c3017 (diff)
IB/mlx4: Sanity check userspace send queue sizes
Add sanity checks to send queue sizes passed in from userspace. The minimum sq stride value below is taken from the MT25408 PRM (section 11.10, Table 306, log_sq_stride definition). Without this check, userspace can submit arbitrarily large/small values for the number of WQEs and the stride, which can crash the kernel. Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 31a480e5b0d0..6b3322486b5e 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -63,6 +63,10 @@ struct mlx4_ib_sqp {
63 u8 header_buf[MLX4_IB_UD_HEADER_SIZE]; 63 u8 header_buf[MLX4_IB_UD_HEADER_SIZE];
64}; 64};
65 65
66enum {
67 MLX4_IB_MIN_SQ_STRIDE = 6
68};
69
66static const __be32 mlx4_ib_opcode[] = { 70static const __be32 mlx4_ib_opcode[] = {
67 [IB_WR_SEND] = __constant_cpu_to_be32(MLX4_OPCODE_SEND), 71 [IB_WR_SEND] = __constant_cpu_to_be32(MLX4_OPCODE_SEND),
68 [IB_WR_SEND_WITH_IMM] = __constant_cpu_to_be32(MLX4_OPCODE_SEND_IMM), 72 [IB_WR_SEND_WITH_IMM] = __constant_cpu_to_be32(MLX4_OPCODE_SEND_IMM),
@@ -285,9 +289,17 @@ static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
285 return 0; 289 return 0;
286} 290}
287 291
288static int set_user_sq_size(struct mlx4_ib_qp *qp, 292static int set_user_sq_size(struct mlx4_ib_dev *dev,
293 struct mlx4_ib_qp *qp,
289 struct mlx4_ib_create_qp *ucmd) 294 struct mlx4_ib_create_qp *ucmd)
290{ 295{
296 /* Sanity check SQ size before proceeding */
297 if ((1 << ucmd->log_sq_bb_count) > dev->dev->caps.max_wqes ||
298 ucmd->log_sq_stride >
299 ilog2(roundup_pow_of_two(dev->dev->caps.max_sq_desc_sz)) ||
300 ucmd->log_sq_stride < MLX4_IB_MIN_SQ_STRIDE)
301 return -EINVAL;
302
291 qp->sq.wqe_cnt = 1 << ucmd->log_sq_bb_count; 303 qp->sq.wqe_cnt = 1 << ucmd->log_sq_bb_count;
292 qp->sq.wqe_shift = ucmd->log_sq_stride; 304 qp->sq.wqe_shift = ucmd->log_sq_stride;
293 305
@@ -330,7 +342,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
330 342
331 qp->sq_no_prefetch = ucmd.sq_no_prefetch; 343 qp->sq_no_prefetch = ucmd.sq_no_prefetch;
332 344
333 err = set_user_sq_size(qp, &ucmd); 345 err = set_user_sq_size(dev, qp, &ucmd);
334 if (err) 346 if (err)
335 goto err; 347 goto err;
336 348