Skip to contentSkip to conversation

IB/mlx4: prevent undefined shift in set_user_sq_size()

PATCH In review Dan Carpenter 3 participants 4 messages Jun 8, 2019 – Jun 11, 2019

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 IB/mlx4: prevent undefined shift in set_user_sq_size()

The ucmd->log_sq_bb_count is a u8 that comes from the user. If it's larger than the number of bits in an int then that's undefined behavior. It turns out this doesn't really cause an issue at runtime but it's still nice to clean it up.

---
 drivers/infiniband/hw/mlx4/qp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/infiniband/hw/mlx4/qp.c +2 -1
index 5221c0794d1d..9f6eb23e8044 100644
@@ -439,7 +439,8 @@ static int set_user_sq_size(struct mlx4_ib_dev *dev,
 			    struct mlx4_ib_create_qp *ucmd)
 {
 	/* Sanity check SQ size before proceeding */
-	if ((1 << ucmd->log_sq_bb_count) > dev->dev->caps.max_wqes	 ||
+	if (ucmd->log_sq_bb_count > 31					 ||
+	    (1 << ucmd->log_sq_bb_count) > dev->dev->caps.max_wqes	 ||
 	    ucmd->log_sq_stride >
 		ilog2(roundup_pow_of_two(dev->dev->caps.max_sq_desc_sz)) ||
 	    ucmd->log_sq_stride < MLX4_IB_MIN_SQ_STRIDE)
Signature · 1 line
2.20.1
#1 lore raw
Quoted 15 lines · Dan Carpenter

The ucmd->log_sq_bb_count is a u8 that comes from the user. If it's larger than the number of bits in an int then that's undefined behavior. It turns out this doesn't really cause an issue at runtime but it's still nice to clean it up.

---
 drivers/infiniband/hw/mlx4/qp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/infiniband/hw/mlx4/qp.c +0 -0
index 5221c0794d1d..9f6eb23e8044 100644

drivers/infiniband/hw/mlx4/qp.c static int set_user_sq_size(struct mlx4_ib_dev *dev, · line 443

Quoted 6 lines
drivers/infiniband/hw/mlx4/qp.c +2 -1
@@ -439,7 +439,8 @@ static int set_user_sq_size(struct mlx4_ib_dev *dev,
 			    struct mlx4_ib_create_qp *ucmd)
 {
 	/* Sanity check SQ size before proceeding */
-	if ((1 << ucmd->log_sq_bb_count) > dev->dev->caps.max_wqes	 ||
+	if (ucmd->log_sq_bb_count > 31					 ||
+	    (1 << ucmd->log_sq_bb_count) > dev->dev->caps.max_wqes	 ||

Surely this should use check_shl_overflow() ?

Jason

#2 lore raw
Quoted 11 lines · Jason Gunthorpe
Quoted 10 lines · Dan Carpenter

The ucmd->log_sq_bb_count is a u8 that comes from the user. If it's larger than the number of bits in an int then that's undefined behavior. It turns out this doesn't really cause an issue at runtime but it's still nice to clean it up.

---
 drivers/infiniband/hw/mlx4/qp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
Quoted 13 lines

drivers/infiniband/hw/mlx4/qp.c static int set_user_sq_size(struct mlx4_ib_dev *dev, · line 443

Quoted 11 lines
drivers/infiniband/hw/mlx4/qp.c +2 -1
index 5221c0794d1d..9f6eb23e8044 100644
@@ -439,7 +439,8 @@ static int set_user_sq_size(struct mlx4_ib_dev *dev,
 			    struct mlx4_ib_create_qp *ucmd)
 {
 	/* Sanity check SQ size before proceeding */
-	if ((1 << ucmd->log_sq_bb_count) > dev->dev->caps.max_wqes	 ||
+	if (ucmd->log_sq_bb_count > 31					 ||
+	    (1 << ucmd->log_sq_bb_count) > dev->dev->caps.max_wqes	 ||

Surely this should use check_shl_overflow() ?

Yes

Quoted 2 lines

Jason

#3 lore raw
In reply to Jason Gunthorpe
Quoted 11 lines · Jason Gunthorpe
Quoted 10 lines · Dan Carpenter

The ucmd->log_sq_bb_count is a u8 that comes from the user. If it's larger than the number of bits in an int then that's undefined behavior. It turns out this doesn't really cause an issue at runtime but it's still nice to clean it up.

---
 drivers/infiniband/hw/mlx4/qp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
Quoted 14 lines

drivers/infiniband/hw/mlx4/qp.c static int set_user_sq_size(struct mlx4_ib_dev *dev, · line 443

Quoted 11 lines
drivers/infiniband/hw/mlx4/qp.c +2 -1
index 5221c0794d1d..9f6eb23e8044 100644
@@ -439,7 +439,8 @@ static int set_user_sq_size(struct mlx4_ib_dev *dev,
 			    struct mlx4_ib_create_qp *ucmd)
 {
 	/* Sanity check SQ size before proceeding */
-	if ((1 << ucmd->log_sq_bb_count) > dev->dev->caps.max_wqes	 ||
+	if (ucmd->log_sq_bb_count > 31					 ||
+	    (1 << ucmd->log_sq_bb_count) > dev->dev->caps.max_wqes	 ||

Surely this should use check_shl_overflow() ?

Same for the other one I sent. I'll resend in a couple days. No rush.

regards,
dan carpenter