Check port number supplied by user verbs cmds in ibcore.

The ib_uverbs_create_ah() ind ib_uverbs_modify_qp() calls receive
the port number from user input as part of its attributes and assumes
it is valid. Down on the stack, that parameter is used to access kernel
data structures.  If the value is invalid, the kernel accesses memory
it should not.  To prevent this, verify the port number before using it.

Linux commit:
5ecce4c9b17bed4dc9cb58bfb10447307569b77b
a62ab66b13a0f9bcb17b7b761f6670941ed5cd62
5a7a88f1b488e4ee49eb3d5b82612d4d9ffdf2c3

MFC after:		1 week
Sponsored by:		Mellanox Technologies
This commit is contained in:
Hans Petter Selasky 2018-07-17 09:29:14 +00:00
parent 56326b4755
commit f736cb92cf
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=336383
3 changed files with 31 additions and 0 deletions

View File

@ -983,6 +983,8 @@ int rdma_init_qp_attr(struct rdma_cm_id *id, struct ib_qp_attr *qp_attr,
} else
ret = iw_cm_init_qp_attr(id_priv->cm_id.iw, qp_attr,
qp_attr_mask);
qp_attr->port_num = id_priv->id.port_num;
*qp_attr_mask |= IB_QP_PORT;
} else
ret = -ENOSYS;

View File

@ -2366,6 +2366,25 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
goto out;
}
if ((cmd.attr_mask & IB_QP_PORT) &&
!rdma_is_port_valid(qp->device, cmd.port_num)) {
ret = -EINVAL;
goto release_qp;
}
if ((cmd.attr_mask & IB_QP_AV) &&
!rdma_is_port_valid(qp->device, cmd.dest.port_num)) {
ret = -EINVAL;
goto release_qp;
}
if ((cmd.attr_mask & IB_QP_ALT_PATH) &&
(!rdma_is_port_valid(qp->device, cmd.alt_port_num) ||
!rdma_is_port_valid(qp->device, cmd.alt_dest.port_num))) {
ret = -EINVAL;
goto release_qp;
}
attr->qp_state = cmd.qp_state;
attr->cur_qp_state = cmd.cur_qp_state;
attr->path_mtu = cmd.path_mtu;
@ -2896,6 +2915,9 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT;
if (!rdma_is_port_valid(ib_dev, cmd.attr.port_num))
return -EINVAL;
INIT_UDATA(&udata, buf + sizeof(cmd),
(unsigned long)cmd.response + sizeof(resp),
in_len - sizeof(cmd), out_len - sizeof(resp));

View File

@ -2260,6 +2260,13 @@ static inline u8 rdma_end_port(const struct ib_device *device)
return rdma_cap_ib_switch(device) ? 0 : device->phys_port_cnt;
}
static inline int rdma_is_port_valid(const struct ib_device *device,
unsigned int port)
{
return (port >= rdma_start_port(device) &&
port <= rdma_end_port(device));
}
static inline bool rdma_protocol_ib(const struct ib_device *device, u8 port_num)
{
return device->port_immutable[port_num].core_cap_flags & RDMA_CORE_CAP_PROT_IB;