rxe: Fix a sleep-in-atomic bug in post_one_send
authorJia-Ju Bai <baijiaju1990@163.com>
Mon, 5 Jun 2017 12:23:40 +0000 (20:23 +0800)
committerDoug Ledford <dledford@redhat.com>
Wed, 14 Jun 2017 17:02:01 +0000 (13:02 -0400)
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>
drivers/infiniband/sw/rxe/rxe_verbs.c

index 83d709e74dfb87ab0dcec30c87f0e49cd57022d2..073e66783f1dd8a4b62f9fc59a84319b507b51b8 100644 (file)
@@ -740,13 +740,8 @@ static int init_send_wqe(struct rxe_qp *qp, struct ib_send_wr *ibwr,
 
                sge = ibwr->sg_list;
                for (i = 0; i < num_sge; i++, sge++) {
-                       if (qp->is_user && copy_from_user(p, (__user void *)
-                                           (uintptr_t)sge->addr, sge->length))
-                               return -EFAULT;
-
-                       else if (!qp->is_user)
-                               memcpy(p, (void *)(uintptr_t)sge->addr,
-                                      sge->length);
+                       memcpy(p, (void *)(uintptr_t)sge->addr,
+                                       sge->length);
 
                        p += sge->length;
                }