diff options
author | Jia-Ju Bai <baijiaju1990@163.com> | 2017-06-05 08:23:40 -0400 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2017-06-14 13:02:01 -0400 |
commit | 07d432bb97f19dd5e784175152f9fce3b2646133 (patch) | |
tree | f7467081cde8500b5746a39cd8692f95532b22f0 | |
parent | e57bb6be5e095351086d3e6de9853a0763342535 (diff) |
rxe: Fix a sleep-in-atomic bug in post_one_send
The driver may sleep under a spin lock, and the function call path is:
post_one_send (acquire the lock by spin_lock_irqsave)
init_send_wqe
copy_from_user --> may sleep
There is no flow that makes "qp->is_user" true, and copy_from_user may
cause bug when a non-user pointer is used. So the lines of copy_from_user
and check of "qp->is_user" are removed.
Signed-off-by: Jia-Ju Bai <baijiaju1990@163.com>
Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
Acked-by: Moni Shoua <monis@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r-- | drivers/infiniband/sw/rxe/rxe_verbs.c | 9 |
1 files changed, 2 insertions, 7 deletions
diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c index 83d709e74dfb..073e66783f1d 100644 --- a/drivers/infiniband/sw/rxe/rxe_verbs.c +++ b/drivers/infiniband/sw/rxe/rxe_verbs.c | |||
@@ -740,13 +740,8 @@ static int init_send_wqe(struct rxe_qp *qp, struct ib_send_wr *ibwr, | |||
740 | 740 | ||
741 | sge = ibwr->sg_list; | 741 | sge = ibwr->sg_list; |
742 | for (i = 0; i < num_sge; i++, sge++) { | 742 | for (i = 0; i < num_sge; i++, sge++) { |
743 | if (qp->is_user && copy_from_user(p, (__user void *) | 743 | memcpy(p, (void *)(uintptr_t)sge->addr, |
744 | (uintptr_t)sge->addr, sge->length)) | 744 | sge->length); |
745 | return -EFAULT; | ||
746 | |||
747 | else if (!qp->is_user) | ||
748 | memcpy(p, (void *)(uintptr_t)sge->addr, | ||
749 | sge->length); | ||
750 | 745 | ||
751 | p += sge->length; | 746 | p += sge->length; |
752 | } | 747 | } |