aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSagi Grimberg <sagi@grimberg.me>2018-06-19 08:34:09 -0400
committerChristoph Hellwig <hch@lst.de>2018-06-20 08:20:10 -0400
commit3d0641015bf73aaa1cb54c936674959e7805070f (patch)
tree5ed6d9e3ded85d03728943f2ab4b10269e3493e0
parent9c24c10a2c1e1bb478b6bb70612d9e885aee044f (diff)
nvme-rdma: fix possible double free condition when failing to create a controller
Failures after nvme_init_ctrl will defer resource cleanups to .free_ctrl when the reference is released, hence we should not free the controller queues for these failures. Fix that by moving controller queues allocation before controller initialization and correctly freeing them for failures before initialization and skip them for failures after initialization. Signed-off-by: Sagi Grimberg <sagi@grimberg.me> Signed-off-by: Christoph Hellwig <hch@lst.de>
-rw-r--r--drivers/nvme/host/rdma.c20
1 files changed, 10 insertions, 10 deletions
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index c9424da0d23e..bcb0e5d6343d 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -888,9 +888,9 @@ static void nvme_rdma_free_ctrl(struct nvme_ctrl *nctrl)
888 list_del(&ctrl->list); 888 list_del(&ctrl->list);
889 mutex_unlock(&nvme_rdma_ctrl_mutex); 889 mutex_unlock(&nvme_rdma_ctrl_mutex);
890 890
891 kfree(ctrl->queues);
892 nvmf_free_options(nctrl->opts); 891 nvmf_free_options(nctrl->opts);
893free_ctrl: 892free_ctrl:
893 kfree(ctrl->queues);
894 kfree(ctrl); 894 kfree(ctrl);
895} 895}
896 896
@@ -1932,11 +1932,6 @@ static struct nvme_ctrl *nvme_rdma_create_ctrl(struct device *dev,
1932 goto out_free_ctrl; 1932 goto out_free_ctrl;
1933 } 1933 }
1934 1934
1935 ret = nvme_init_ctrl(&ctrl->ctrl, dev, &nvme_rdma_ctrl_ops,
1936 0 /* no quirks, we're perfect! */);
1937 if (ret)
1938 goto out_free_ctrl;
1939
1940 INIT_DELAYED_WORK(&ctrl->reconnect_work, 1935 INIT_DELAYED_WORK(&ctrl->reconnect_work,
1941 nvme_rdma_reconnect_ctrl_work); 1936 nvme_rdma_reconnect_ctrl_work);
1942 INIT_WORK(&ctrl->err_work, nvme_rdma_error_recovery_work); 1937 INIT_WORK(&ctrl->err_work, nvme_rdma_error_recovery_work);
@@ -1950,14 +1945,19 @@ static struct nvme_ctrl *nvme_rdma_create_ctrl(struct device *dev,
1950 ctrl->queues = kcalloc(ctrl->ctrl.queue_count, sizeof(*ctrl->queues), 1945 ctrl->queues = kcalloc(ctrl->ctrl.queue_count, sizeof(*ctrl->queues),
1951 GFP_KERNEL); 1946 GFP_KERNEL);
1952 if (!ctrl->queues) 1947 if (!ctrl->queues)
1953 goto out_uninit_ctrl; 1948 goto out_free_ctrl;
1949
1950 ret = nvme_init_ctrl(&ctrl->ctrl, dev, &nvme_rdma_ctrl_ops,
1951 0 /* no quirks, we're perfect! */);
1952 if (ret)
1953 goto out_kfree_queues;
1954 1954
1955 changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING); 1955 changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING);
1956 WARN_ON_ONCE(!changed); 1956 WARN_ON_ONCE(!changed);
1957 1957
1958 ret = nvme_rdma_configure_admin_queue(ctrl, true); 1958 ret = nvme_rdma_configure_admin_queue(ctrl, true);
1959 if (ret) 1959 if (ret)
1960 goto out_kfree_queues; 1960 goto out_uninit_ctrl;
1961 1961
1962 /* sanity check icdoff */ 1962 /* sanity check icdoff */
1963 if (ctrl->ctrl.icdoff) { 1963 if (ctrl->ctrl.icdoff) {
@@ -2014,14 +2014,14 @@ static struct nvme_ctrl *nvme_rdma_create_ctrl(struct device *dev,
2014 2014
2015out_remove_admin_queue: 2015out_remove_admin_queue:
2016 nvme_rdma_destroy_admin_queue(ctrl, true); 2016 nvme_rdma_destroy_admin_queue(ctrl, true);
2017out_kfree_queues:
2018 kfree(ctrl->queues);
2019out_uninit_ctrl: 2017out_uninit_ctrl:
2020 nvme_uninit_ctrl(&ctrl->ctrl); 2018 nvme_uninit_ctrl(&ctrl->ctrl);
2021 nvme_put_ctrl(&ctrl->ctrl); 2019 nvme_put_ctrl(&ctrl->ctrl);
2022 if (ret > 0) 2020 if (ret > 0)
2023 ret = -EIO; 2021 ret = -EIO;
2024 return ERR_PTR(ret); 2022 return ERR_PTR(ret);
2023out_kfree_queues:
2024 kfree(ctrl->queues);
2025out_free_ctrl: 2025out_free_ctrl:
2026 kfree(ctrl); 2026 kfree(ctrl);
2027 return ERR_PTR(ret); 2027 return ERR_PTR(ret);