]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
RDMA/rxe: Fix unsafe drain work queue code
authorBob Pearson <rpearsonhpe@gmail.com>
Tue, 20 Jun 2023 13:55:21 +0000 (08:55 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 13 Sep 2023 07:48:28 +0000 (09:48 +0200)
[ 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
drivers/infiniband/sw/rxe/rxe_resp.c

index f46c5a5fd0aea4d4c0530d054949a8867013053a..44fece204abdd55d42a9c731f3d6ed4e66ce96c5 100644 (file)
@@ -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);
index ee68306555b990ca169175bae2c31003737d62aa..ed5af55237d9ffbf913a8191f7e8f5768cf8fc9b 100644 (file)
@@ -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);