aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-07-13 15:42:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-07-13 15:42:14 -0400
commit4659fc8484b707c161b14324df0e3a2f5d03f050 (patch)
tree5f2e1dce44199e0ee19c7f1a7ed6c137b606798a
parent2a7e1211e130c51a2b5743ecf247645ac8e936ee (diff)
parentd63c46734c545ad0488761059004a65c46efdde3 (diff)
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
Pull rdma fixes from Jason Gunthorpe: "Things have been quite slow, only 6 RC patches have been sent to the list. Regression, user visible bugs, and crashing fixes: - cxgb4 could wrongly fail MR creation due to a typo - various crashes if the wrong QP type is mixed in with APIs that expect other types - syzkaller oops - using ERR_PTR and NULL together cases HFI1 to crash in some cases - mlx5 memory leak in error unwind" * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: RDMA/mlx5: Fix memory leak in mlx5_ib_create_srq() error path RDMA/uverbs: Don't fail in creation of multiple flows IB/hfi1: Fix incorrect mixing of ERR_PTR and NULL return values RDMA/uverbs: Fix slab-out-of-bounds in ib_uverbs_ex_create_flow RDMA/uverbs: Protect from attempts to create flows on unsupported QP iw_cxgb4: correctly enforce the max reg_mr depth
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c28
-rw-r--r--drivers/infiniband/hw/cxgb4/mem.c2
-rw-r--r--drivers/infiniband/hw/hfi1/rc.c2
-rw-r--r--drivers/infiniband/hw/hfi1/uc.c4
-rw-r--r--drivers/infiniband/hw/hfi1/ud.c4
-rw-r--r--drivers/infiniband/hw/hfi1/verbs_txreq.c4
-rw-r--r--drivers/infiniband/hw/hfi1/verbs_txreq.h4
-rw-r--r--drivers/infiniband/hw/mlx5/srq.c18
8 files changed, 39 insertions, 27 deletions
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 3e90b6a1d9d2..cc06e8404e9b 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -3488,8 +3488,8 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file,
3488 struct ib_flow_attr *flow_attr; 3488 struct ib_flow_attr *flow_attr;
3489 struct ib_qp *qp; 3489 struct ib_qp *qp;
3490 struct ib_uflow_resources *uflow_res; 3490 struct ib_uflow_resources *uflow_res;
3491 struct ib_uverbs_flow_spec_hdr *kern_spec;
3491 int err = 0; 3492 int err = 0;
3492 void *kern_spec;
3493 void *ib_spec; 3493 void *ib_spec;
3494 int i; 3494 int i;
3495 3495
@@ -3538,8 +3538,8 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file,
3538 if (!kern_flow_attr) 3538 if (!kern_flow_attr)
3539 return -ENOMEM; 3539 return -ENOMEM;
3540 3540
3541 memcpy(kern_flow_attr, &cmd.flow_attr, sizeof(*kern_flow_attr)); 3541 *kern_flow_attr = cmd.flow_attr;
3542 err = ib_copy_from_udata(kern_flow_attr + 1, ucore, 3542 err = ib_copy_from_udata(&kern_flow_attr->flow_specs, ucore,
3543 cmd.flow_attr.size); 3543 cmd.flow_attr.size);
3544 if (err) 3544 if (err)
3545 goto err_free_attr; 3545 goto err_free_attr;
@@ -3559,6 +3559,11 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file,
3559 goto err_uobj; 3559 goto err_uobj;
3560 } 3560 }
3561 3561
3562 if (qp->qp_type != IB_QPT_UD && qp->qp_type != IB_QPT_RAW_PACKET) {
3563 err = -EINVAL;
3564 goto err_put;
3565 }
3566
3562 flow_attr = kzalloc(struct_size(flow_attr, flows, 3567 flow_attr = kzalloc(struct_size(flow_attr, flows,
3563 cmd.flow_attr.num_of_specs), GFP_KERNEL); 3568 cmd.flow_attr.num_of_specs), GFP_KERNEL);
3564 if (!flow_attr) { 3569 if (!flow_attr) {
@@ -3578,21 +3583,22 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file,
3578 flow_attr->flags = kern_flow_attr->flags; 3583 flow_attr->flags = kern_flow_attr->flags;
3579 flow_attr->size = sizeof(*flow_attr); 3584 flow_attr->size = sizeof(*flow_attr);
3580 3585
3581 kern_spec = kern_flow_attr + 1; 3586 kern_spec = kern_flow_attr->flow_specs;
3582 ib_spec = flow_attr + 1; 3587 ib_spec = flow_attr + 1;
3583 for (i = 0; i < flow_attr->num_of_specs && 3588 for (i = 0; i < flow_attr->num_of_specs &&
3584 cmd.flow_attr.size > offsetof(struct ib_uverbs_flow_spec, reserved) && 3589 cmd.flow_attr.size >= sizeof(*kern_spec) &&
3585 cmd.flow_attr.size >= 3590 cmd.flow_attr.size >= kern_spec->size;
3586 ((struct ib_uverbs_flow_spec *)kern_spec)->size; i++) { 3591 i++) {
3587 err = kern_spec_to_ib_spec(file->ucontext, kern_spec, ib_spec, 3592 err = kern_spec_to_ib_spec(
3588 uflow_res); 3593 file->ucontext, (struct ib_uverbs_flow_spec *)kern_spec,
3594 ib_spec, uflow_res);
3589 if (err) 3595 if (err)
3590 goto err_free; 3596 goto err_free;
3591 3597
3592 flow_attr->size += 3598 flow_attr->size +=
3593 ((union ib_flow_spec *) ib_spec)->size; 3599 ((union ib_flow_spec *) ib_spec)->size;
3594 cmd.flow_attr.size -= ((struct ib_uverbs_flow_spec *)kern_spec)->size; 3600 cmd.flow_attr.size -= kern_spec->size;
3595 kern_spec += ((struct ib_uverbs_flow_spec *) kern_spec)->size; 3601 kern_spec = ((void *)kern_spec) + kern_spec->size;
3596 ib_spec += ((union ib_flow_spec *) ib_spec)->size; 3602 ib_spec += ((union ib_flow_spec *) ib_spec)->size;
3597 } 3603 }
3598 if (cmd.flow_attr.size || (i != flow_attr->num_of_specs)) { 3604 if (cmd.flow_attr.size || (i != flow_attr->num_of_specs)) {
diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c
index 1445918e3239..7b76e6f81aeb 100644
--- a/drivers/infiniband/hw/cxgb4/mem.c
+++ b/drivers/infiniband/hw/cxgb4/mem.c
@@ -774,7 +774,7 @@ static int c4iw_set_page(struct ib_mr *ibmr, u64 addr)
774{ 774{
775 struct c4iw_mr *mhp = to_c4iw_mr(ibmr); 775 struct c4iw_mr *mhp = to_c4iw_mr(ibmr);
776 776
777 if (unlikely(mhp->mpl_len == mhp->max_mpl_len)) 777 if (unlikely(mhp->mpl_len == mhp->attr.pbl_size))
778 return -ENOMEM; 778 return -ENOMEM;
779 779
780 mhp->mpl[mhp->mpl_len++] = addr; 780 mhp->mpl[mhp->mpl_len++] = addr;
diff --git a/drivers/infiniband/hw/hfi1/rc.c b/drivers/infiniband/hw/hfi1/rc.c
index 1a1a47ac53c6..f15c93102081 100644
--- a/drivers/infiniband/hw/hfi1/rc.c
+++ b/drivers/infiniband/hw/hfi1/rc.c
@@ -271,7 +271,7 @@ int hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
271 271
272 lockdep_assert_held(&qp->s_lock); 272 lockdep_assert_held(&qp->s_lock);
273 ps->s_txreq = get_txreq(ps->dev, qp); 273 ps->s_txreq = get_txreq(ps->dev, qp);
274 if (IS_ERR(ps->s_txreq)) 274 if (!ps->s_txreq)
275 goto bail_no_tx; 275 goto bail_no_tx;
276 276
277 if (priv->hdr_type == HFI1_PKT_TYPE_9B) { 277 if (priv->hdr_type == HFI1_PKT_TYPE_9B) {
diff --git a/drivers/infiniband/hw/hfi1/uc.c b/drivers/infiniband/hw/hfi1/uc.c
index b7b671017e59..e254dcec6f64 100644
--- a/drivers/infiniband/hw/hfi1/uc.c
+++ b/drivers/infiniband/hw/hfi1/uc.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright(c) 2015, 2016 Intel Corporation. 2 * Copyright(c) 2015 - 2018 Intel Corporation.
3 * 3 *
4 * This file is provided under a dual BSD/GPLv2 license. When using or 4 * This file is provided under a dual BSD/GPLv2 license. When using or
5 * redistributing this file, you may do so under either license. 5 * redistributing this file, you may do so under either license.
@@ -72,7 +72,7 @@ int hfi1_make_uc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
72 int middle = 0; 72 int middle = 0;
73 73
74 ps->s_txreq = get_txreq(ps->dev, qp); 74 ps->s_txreq = get_txreq(ps->dev, qp);
75 if (IS_ERR(ps->s_txreq)) 75 if (!ps->s_txreq)
76 goto bail_no_tx; 76 goto bail_no_tx;
77 77
78 if (!(ib_rvt_state_ops[qp->state] & RVT_PROCESS_SEND_OK)) { 78 if (!(ib_rvt_state_ops[qp->state] & RVT_PROCESS_SEND_OK)) {
diff --git a/drivers/infiniband/hw/hfi1/ud.c b/drivers/infiniband/hw/hfi1/ud.c
index 1ab332f1866e..70d39fc450a1 100644
--- a/drivers/infiniband/hw/hfi1/ud.c
+++ b/drivers/infiniband/hw/hfi1/ud.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright(c) 2015, 2016 Intel Corporation. 2 * Copyright(c) 2015 - 2018 Intel Corporation.
3 * 3 *
4 * This file is provided under a dual BSD/GPLv2 license. When using or 4 * This file is provided under a dual BSD/GPLv2 license. When using or
5 * redistributing this file, you may do so under either license. 5 * redistributing this file, you may do so under either license.
@@ -503,7 +503,7 @@ int hfi1_make_ud_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
503 u32 lid; 503 u32 lid;
504 504
505 ps->s_txreq = get_txreq(ps->dev, qp); 505 ps->s_txreq = get_txreq(ps->dev, qp);
506 if (IS_ERR(ps->s_txreq)) 506 if (!ps->s_txreq)
507 goto bail_no_tx; 507 goto bail_no_tx;
508 508
509 if (!(ib_rvt_state_ops[qp->state] & RVT_PROCESS_NEXT_SEND_OK)) { 509 if (!(ib_rvt_state_ops[qp->state] & RVT_PROCESS_NEXT_SEND_OK)) {
diff --git a/drivers/infiniband/hw/hfi1/verbs_txreq.c b/drivers/infiniband/hw/hfi1/verbs_txreq.c
index 873e48ea923f..c4ab2d5b4502 100644
--- a/drivers/infiniband/hw/hfi1/verbs_txreq.c
+++ b/drivers/infiniband/hw/hfi1/verbs_txreq.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright(c) 2016 - 2017 Intel Corporation. 2 * Copyright(c) 2016 - 2018 Intel Corporation.
3 * 3 *
4 * This file is provided under a dual BSD/GPLv2 license. When using or 4 * This file is provided under a dual BSD/GPLv2 license. When using or
5 * redistributing this file, you may do so under either license. 5 * redistributing this file, you may do so under either license.
@@ -94,7 +94,7 @@ struct verbs_txreq *__get_txreq(struct hfi1_ibdev *dev,
94 struct rvt_qp *qp) 94 struct rvt_qp *qp)
95 __must_hold(&qp->s_lock) 95 __must_hold(&qp->s_lock)
96{ 96{
97 struct verbs_txreq *tx = ERR_PTR(-EBUSY); 97 struct verbs_txreq *tx = NULL;
98 98
99 write_seqlock(&dev->txwait_lock); 99 write_seqlock(&dev->txwait_lock);
100 if (ib_rvt_state_ops[qp->state] & RVT_PROCESS_RECV_OK) { 100 if (ib_rvt_state_ops[qp->state] & RVT_PROCESS_RECV_OK) {
diff --git a/drivers/infiniband/hw/hfi1/verbs_txreq.h b/drivers/infiniband/hw/hfi1/verbs_txreq.h
index 729244c3086c..1c19bbc764b2 100644
--- a/drivers/infiniband/hw/hfi1/verbs_txreq.h
+++ b/drivers/infiniband/hw/hfi1/verbs_txreq.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright(c) 2016 Intel Corporation. 2 * Copyright(c) 2016 - 2018 Intel Corporation.
3 * 3 *
4 * This file is provided under a dual BSD/GPLv2 license. When using or 4 * This file is provided under a dual BSD/GPLv2 license. When using or
5 * redistributing this file, you may do so under either license. 5 * redistributing this file, you may do so under either license.
@@ -83,7 +83,7 @@ static inline struct verbs_txreq *get_txreq(struct hfi1_ibdev *dev,
83 if (unlikely(!tx)) { 83 if (unlikely(!tx)) {
84 /* call slow path to get the lock */ 84 /* call slow path to get the lock */
85 tx = __get_txreq(dev, qp); 85 tx = __get_txreq(dev, qp);
86 if (IS_ERR(tx)) 86 if (!tx)
87 return tx; 87 return tx;
88 } 88 }
89 tx->qp = qp; 89 tx->qp = qp;
diff --git a/drivers/infiniband/hw/mlx5/srq.c b/drivers/infiniband/hw/mlx5/srq.c
index 0af7b7905550..f5de5adc9b1a 100644
--- a/drivers/infiniband/hw/mlx5/srq.c
+++ b/drivers/infiniband/hw/mlx5/srq.c
@@ -266,18 +266,24 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
266 266
267 desc_size = sizeof(struct mlx5_wqe_srq_next_seg) + 267 desc_size = sizeof(struct mlx5_wqe_srq_next_seg) +
268 srq->msrq.max_gs * sizeof(struct mlx5_wqe_data_seg); 268 srq->msrq.max_gs * sizeof(struct mlx5_wqe_data_seg);
269 if (desc_size == 0 || srq->msrq.max_gs > desc_size) 269 if (desc_size == 0 || srq->msrq.max_gs > desc_size) {
270 return ERR_PTR(-EINVAL); 270 err = -EINVAL;
271 goto err_srq;
272 }
271 desc_size = roundup_pow_of_two(desc_size); 273 desc_size = roundup_pow_of_two(desc_size);
272 desc_size = max_t(size_t, 32, desc_size); 274 desc_size = max_t(size_t, 32, desc_size);
273 if (desc_size < sizeof(struct mlx5_wqe_srq_next_seg)) 275 if (desc_size < sizeof(struct mlx5_wqe_srq_next_seg)) {
274 return ERR_PTR(-EINVAL); 276 err = -EINVAL;
277 goto err_srq;
278 }
275 srq->msrq.max_avail_gather = (desc_size - sizeof(struct mlx5_wqe_srq_next_seg)) / 279 srq->msrq.max_avail_gather = (desc_size - sizeof(struct mlx5_wqe_srq_next_seg)) /
276 sizeof(struct mlx5_wqe_data_seg); 280 sizeof(struct mlx5_wqe_data_seg);
277 srq->msrq.wqe_shift = ilog2(desc_size); 281 srq->msrq.wqe_shift = ilog2(desc_size);
278 buf_size = srq->msrq.max * desc_size; 282 buf_size = srq->msrq.max * desc_size;
279 if (buf_size < desc_size) 283 if (buf_size < desc_size) {
280 return ERR_PTR(-EINVAL); 284 err = -EINVAL;
285 goto err_srq;
286 }
281 in.type = init_attr->srq_type; 287 in.type = init_attr->srq_type;
282 288
283 if (pd->uobject) 289 if (pd->uobject)