| From 31ae0995a40a513008d8853b5a2a63794db62f46 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 20 Jun 2023 08:55:21 -0500 |
| Subject: RDMA/rxe: Fix unsafe drain work queue code |
| |
| From: Bob Pearson <rpearsonhpe@gmail.com> |
| |
| [ Upstream commit 5993b75d0bc71cd2b441d174b028fc36180f032c ] |
| |
| If create_qp does not fully succeed it is possible for qp cleanup |
| code to attempt to drain the send or recv work queues before the |
| queues have been created causing a seg fault. This patch checks |
| to see if the queues exist before attempting to drain them. |
| |
| Link: https://lore.kernel.org/r/20230620135519.9365-3-rpearsonhpe@gmail.com |
| Reported-by: syzbot+2da1965168e7dbcba136@syzkaller.appspotmail.com |
| Closes: https://lore.kernel.org/linux-rdma/00000000000012d89205fe7cfe00@google.com/raw |
| Fixes: 49dc9c1f0c7e ("RDMA/rxe: Cleanup reset state handling in rxe_resp.c") |
| Fixes: fbdeb828a21f ("RDMA/rxe: Cleanup error state handling in rxe_comp.c") |
| Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com> |
| Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/infiniband/sw/rxe/rxe_comp.c | 4 ++++ |
| drivers/infiniband/sw/rxe/rxe_resp.c | 4 ++++ |
| 2 files changed, 8 insertions(+) |
| |
| diff --git a/drivers/infiniband/sw/rxe/rxe_comp.c b/drivers/infiniband/sw/rxe/rxe_comp.c |
| index f46c5a5fd0aea..44fece204abdd 100644 |
| --- a/drivers/infiniband/sw/rxe/rxe_comp.c |
| +++ b/drivers/infiniband/sw/rxe/rxe_comp.c |
| @@ -597,6 +597,10 @@ static void flush_send_queue(struct rxe_qp *qp, bool notify) |
| struct rxe_queue *q = qp->sq.queue; |
| int err; |
| |
| + /* send queue never got created. nothing to do. */ |
| + if (!qp->sq.queue) |
| + return; |
| + |
| while ((wqe = queue_head(q, q->type))) { |
| if (notify) { |
| err = flush_send_wqe(qp, wqe); |
| diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c |
| index ee68306555b99..ed5af55237d9f 100644 |
| --- a/drivers/infiniband/sw/rxe/rxe_resp.c |
| +++ b/drivers/infiniband/sw/rxe/rxe_resp.c |
| @@ -1452,6 +1452,10 @@ static void flush_recv_queue(struct rxe_qp *qp, bool notify) |
| if (qp->srq) |
| return; |
| |
| + /* recv queue not created. nothing to do. */ |
| + if (!qp->rq.queue) |
| + return; |
| + |
| while ((wqe = queue_head(q, q->type))) { |
| if (notify) { |
| err = flush_recv_wqe(qp, wqe); |
| -- |
| 2.40.1 |
| |