lkml.org 
[lkml]   [2018]   [Aug]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.14 089/246] nvme-rdma: stop admin queue before freeing it
    Date
    4.14-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Jianchao Wang <jianchao.w.wang@oracle.com>

    [ Upstream commit 2e050f00a0f0e07467050cb4afae0234941e5bf3 ]

    For any failure after nvme_rdma_start_queue in
    nvme_rdma_configure_admin_queue, the admin queue will be freed with the
    NVME_RDMA_Q_LIVE flag still set. Once nvme_rdma_stop_queue is invoked,
    that will cause a use-after-free.
    BUG: KASAN: use-after-free in rdma_disconnect+0x1f/0xe0 [rdma_cm]

    To fix it, call nvme_rdma_stop_queue for all the failed cases after
    nvme_rdma_start_queue.

    Signed-off-by: Jianchao Wang <jianchao.w.wang@oracle.com>
    Suggested-by: Sagi Grimberg <sagi@grimberg.me>
    Reviewed-by: Max Gurtovoy <maxg@mellanox.com>
    Signed-off-by: Christoph Hellwig <hch@lst.de>
    Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/nvme/host/rdma.c | 10 ++++++----
    1 file changed, 6 insertions(+), 4 deletions(-)

    --- a/drivers/nvme/host/rdma.c
    +++ b/drivers/nvme/host/rdma.c
    @@ -796,7 +796,7 @@ static int nvme_rdma_configure_admin_que
    if (error) {
    dev_err(ctrl->ctrl.device,
    "prop_get NVME_REG_CAP failed\n");
    - goto out_cleanup_queue;
    + goto out_stop_queue;
    }

    ctrl->ctrl.sqsize =
    @@ -804,23 +804,25 @@ static int nvme_rdma_configure_admin_que

    error = nvme_enable_ctrl(&ctrl->ctrl, ctrl->ctrl.cap);
    if (error)
    - goto out_cleanup_queue;
    + goto out_stop_queue;

    ctrl->ctrl.max_hw_sectors =
    (ctrl->max_fr_pages - 1) << (ilog2(SZ_4K) - 9);

    error = nvme_init_identify(&ctrl->ctrl);
    if (error)
    - goto out_cleanup_queue;
    + goto out_stop_queue;

    error = nvme_rdma_alloc_qe(ctrl->queues[0].device->dev,
    &ctrl->async_event_sqe, sizeof(struct nvme_command),
    DMA_TO_DEVICE);
    if (error)
    - goto out_cleanup_queue;
    + goto out_stop_queue;

    return 0;

    +out_stop_queue:
    + nvme_rdma_stop_queue(&ctrl->queues[0]);
    out_cleanup_queue:
    if (new)
    blk_cleanup_queue(ctrl->ctrl.admin_q);

    \
     
     \ /
      Last update: 2018-08-01 20:13    [W:4.116 / U:0.132 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site