1
0
Fork 0

One bug for missing user input validation:

- Refuse invalid port numbers in the modify_qp system call
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iQIcBAABCgAGBQJbZH4AAAoJEDht9xV+IJsausAP/RBqXIgC7qvZGrrmhBo5dF1j
 n3+fmynR6KaGDMYRlEbuj+Ce70HbOWyvHx/KgyEMtejjtldVvQqBmGYGR6Dcpn0/
 NA3VWFm7XaM+Oxg136NwkWtdiwUt0a/Ois6wSZsY6XJkXzTKmlyImcDJx1oQwvxZ
 +WwVx7t3kWoCWTXlcbAmz41gDHJFD7vszavhgz0o7Ik1IloYs4bV7NVgGw/athan
 2M8Df7tZNHhMgZDFhp3HeMbkjgApwnSMbGwtaEuaBZF4y1yEw7tp/xn6b87LzP9N
 1JoVPenCp5+Pzw73FgT2sPY9gfI6RieHH/ZGM09Ng9awwPe44pIPnbH9AF6KxlBB
 xFZT43i33CP1+85NFeSyxDeW3wwYXi48Qup7brtJ91LyD/KUmihAyoBuVaFbfYOr
 lOPn8aMBvyumprSjAGzCiiEO8nrwoGs8ZRMJeQXyBkpT9siPvLAMUt5ZweWl4rD2
 48/oR+KOrJ2rJCLwsmuQBoevxAJZ0/FVlg/o4oBk8ntjbDKVJzTZgEccqN+6sKrj
 W3CgK8RHpXWWIScZHcAseQvdKrrOPNtNszOYtXFF8QjdP1QzQvoisrd9yM1L+/+g
 RlsvMpLTHTF0S+d2mGNtB0xY6jh5HOAT62YNJGt8GNJ4d5c23bQ3s+SuiWLrF+6f
 jKER3Mz0YbwwVR07Ai2h
 =8q1F
 -----END PGP SIGNATURE-----

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma

Pull rdma fix from Jason Gunthorpe:
 "One bug for missing user input validation: refuse invalid port numbers
  in the modify_qp system call"

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma:
  RDMA/uverbs: Expand primary and alt AV port checks
hifive-unleashed-5.1
Linus Torvalds 2018-08-03 10:49:47 -07:00
commit f6229c3958
1 changed files with 54 additions and 5 deletions

View File

@ -1984,15 +1984,64 @@ static int modify_qp(struct ib_uverbs_file *file,
goto release_qp;
}
if ((cmd->base.attr_mask & IB_QP_AV) &&
!rdma_is_port_valid(qp->device, cmd->base.dest.port_num)) {
ret = -EINVAL;
goto release_qp;
if ((cmd->base.attr_mask & IB_QP_AV)) {
if (!rdma_is_port_valid(qp->device, cmd->base.dest.port_num)) {
ret = -EINVAL;
goto release_qp;
}
if (cmd->base.attr_mask & IB_QP_STATE &&
cmd->base.qp_state == IB_QPS_RTR) {
/* We are in INIT->RTR TRANSITION (if we are not,
* this transition will be rejected in subsequent checks).
* In the INIT->RTR transition, we cannot have IB_QP_PORT set,
* but the IB_QP_STATE flag is required.
*
* Since kernel 3.14 (commit dbf727de7440), the uverbs driver,
* when IB_QP_AV is set, has required inclusion of a valid
* port number in the primary AV. (AVs are created and handled
* differently for infiniband and ethernet (RoCE) ports).
*
* Check the port number included in the primary AV against
* the port number in the qp struct, which was set (and saved)
* in the RST->INIT transition.
*/
if (cmd->base.dest.port_num != qp->real_qp->port) {
ret = -EINVAL;
goto release_qp;
}
} else {
/* We are in SQD->SQD. (If we are not, this transition will
* be rejected later in the verbs layer checks).
* Check for both IB_QP_PORT and IB_QP_AV, these can be set
* together in the SQD->SQD transition.
*
* If only IP_QP_AV was set, add in IB_QP_PORT as well (the
* verbs layer driver does not track primary port changes
* resulting from path migration. Thus, in SQD, if the primary
* AV is modified, the primary port should also be modified).
*
* Note that in this transition, the IB_QP_STATE flag
* is not allowed.
*/
if (((cmd->base.attr_mask & (IB_QP_AV | IB_QP_PORT))
== (IB_QP_AV | IB_QP_PORT)) &&
cmd->base.port_num != cmd->base.dest.port_num) {
ret = -EINVAL;
goto release_qp;
}
if ((cmd->base.attr_mask & (IB_QP_AV | IB_QP_PORT))
== IB_QP_AV) {
cmd->base.attr_mask |= IB_QP_PORT;
cmd->base.port_num = cmd->base.dest.port_num;
}
}
}
if ((cmd->base.attr_mask & IB_QP_ALT_PATH) &&
(!rdma_is_port_valid(qp->device, cmd->base.alt_port_num) ||
!rdma_is_port_valid(qp->device, cmd->base.alt_dest.port_num))) {
!rdma_is_port_valid(qp->device, cmd->base.alt_dest.port_num) ||
cmd->base.alt_port_num != cmd->base.alt_dest.port_num)) {
ret = -EINVAL;
goto release_qp;
}