Blob Blame History Raw
From abb3bf03bcb543915852204b4fdaf6a88873b51a Mon Sep 17 00:00:00 2001
From: Noa Osherovich <noaos@mellanox.com>
Date: Wed, 22 Nov 2017 11:11:21 +0200
Subject: [PATCH rdma-core 1/3] Add a helper function to verify 64 bit comp
 mask

The common check for a mask is as follows:
if (comp_mask & ~COMP_MASK_SUPPORTED_VALUES)
	return EINVAL

This can cause an issue when using 64 bit mask if the supported variable
is signed 32 bit: It will be bitwise inverted and then zeroed to 64
bits. This way wrong bits in the mask that exceed 32 bits will not raise
an error but will be ignored.

Add a helper function in driver.h to be used by providers code and fix
wrong mask checks where the above was found to be applicable.

Signed-off-by: Noa Osherovich <noaos@mellanox.com>
Reviewed-by: Yishai Hadas <yishaih@mellanox.com>
(cherry picked from commit ad4419019a006938731035a766b67838678e6048)
---
 libibverbs/driver.h    | 5 +++++
 providers/mlx4/verbs.c | 4 ++--
 providers/mlx5/verbs.c | 3 ++-
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/libibverbs/driver.h b/libibverbs/driver.h
index 887412de..0b2cd089 100644
--- a/libibverbs/driver.h
+++ b/libibverbs/driver.h
@@ -330,6 +330,11 @@ static inline int verbs_get_srq_num(struct ibv_srq *srq, uint32_t *srq_num)
 	return ENOSYS;
 }
 
+static inline bool check_comp_mask(uint64_t input, uint64_t supported)
+{
+	return (input & ~supported) == 0;
+}
+
 int ibv_query_gid_type(struct ibv_context *context, uint8_t port_num,
 		       unsigned int index, enum ibv_gid_type *type);
 #endif /* INFINIBAND_DRIVER_H */
diff --git a/providers/mlx4/verbs.c b/providers/mlx4/verbs.c
index b966ef2c..7c8f9da8 100644
--- a/providers/mlx4/verbs.c
+++ b/providers/mlx4/verbs.c
@@ -919,8 +919,8 @@ static struct ibv_qp *create_qp_ex(struct ibv_context *context,
 		goto err_free;
 
 	if (mlx4qp_attr) {
-		if (mlx4qp_attr->comp_mask &
-		    ~(MLX4DV_QP_INIT_ATTR_MASK_RESERVED - 1)) {
+		if (!check_comp_mask(mlx4qp_attr->comp_mask,
+		    MLX4DV_QP_INIT_ATTR_MASK_RESERVED - 1)) {
 			errno = EINVAL;
 			goto err_free;
 		}
diff --git a/providers/mlx5/verbs.c b/providers/mlx5/verbs.c
index 2315a0d9..6506bc36 100644
--- a/providers/mlx5/verbs.c
+++ b/providers/mlx5/verbs.c
@@ -433,7 +433,8 @@ static struct ibv_cq_ex *create_cq(struct ibv_context *context,
 	cmd.cqe_size = cqe_sz;
 
 	if (mlx5cq_attr) {
-		if (mlx5cq_attr->comp_mask & ~(MLX5DV_CQ_INIT_ATTR_MASK_RESERVED - 1)) {
+		if (!check_comp_mask(mlx5cq_attr->comp_mask,
+				     MLX5DV_CQ_INIT_ATTR_MASK_RESERVED - 1)) {
 			mlx5_dbg(fp, MLX5_DBG_CQ,
 				   "Unsupported vendor comp_mask for create_cq\n");
 			errno = EINVAL;
-- 
2.12.1