diff options
author | Jens Axboe <axboe@kernel.dk> | 2022-02-03 22:37:02 +0300 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2022-02-03 22:37:02 +0300 |
commit | e8db8c9cadacab5694b0d1bd5f6b3ba6a234a34c (patch) | |
tree | e22751b23d385afd136d273e464879d7b3cc1bd8 /drivers | |
parent | aace2b7a93ca48dc075af8526394bc5d43b5b148 (diff) | |
parent | 6a51abdeb259a56d95f13cc67e3a0838bcda0377 (diff) | |
download | linux-e8db8c9cadacab5694b0d1bd5f6b3ba6a234a34c.tar.xz |
Merge tag 'nvme-5.17-2022-02-03' of git://git.infradead.org/nvme into block-5.17
Pull NVMe fixes from Christoph:
"nvme fixes for Linux 5.17
- fix a use-after-free in rdm and tcp controller reset (Sagi Grimberg)
- fix the state check in nvmf_ctlr_matches_baseopts (Uday Shankar)"
* tag 'nvme-5.17-2022-02-03' of git://git.infradead.org/nvme:
nvme-fabrics: fix state check in nvmf_ctlr_matches_baseopts()
nvme-rdma: fix possible use-after-free in transport error_recovery work
nvme-tcp: fix possible use-after-free in transport error_recovery work
nvme: fix a possible use-after-free in controller reset during load
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/nvme/host/core.c | 9 | ||||
-rw-r--r-- | drivers/nvme/host/fabrics.h | 1 | ||||
-rw-r--r-- | drivers/nvme/host/rdma.c | 1 | ||||
-rw-r--r-- | drivers/nvme/host/tcp.c | 1 |
4 files changed, 11 insertions, 1 deletions
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 5e0bfda04bd7..961a5f8a44d2 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -4253,7 +4253,14 @@ static void nvme_async_event_work(struct work_struct *work) container_of(work, struct nvme_ctrl, async_event_work); nvme_aen_uevent(ctrl); - ctrl->ops->submit_async_event(ctrl); + + /* + * The transport drivers must guarantee AER submission here is safe by + * flushing ctrl async_event_work after changing the controller state + * from LIVE and before freeing the admin queue. + */ + if (ctrl->state == NVME_CTRL_LIVE) + ctrl->ops->submit_async_event(ctrl); } static bool nvme_ctrl_pp_status(struct nvme_ctrl *ctrl) diff --git a/drivers/nvme/host/fabrics.h b/drivers/nvme/host/fabrics.h index c3203ff1c654..1e3a09cad961 100644 --- a/drivers/nvme/host/fabrics.h +++ b/drivers/nvme/host/fabrics.h @@ -170,6 +170,7 @@ nvmf_ctlr_matches_baseopts(struct nvme_ctrl *ctrl, struct nvmf_ctrl_options *opts) { if (ctrl->state == NVME_CTRL_DELETING || + ctrl->state == NVME_CTRL_DELETING_NOIO || ctrl->state == NVME_CTRL_DEAD || strcmp(opts->subsysnqn, ctrl->opts->subsysnqn) || strcmp(opts->host->nqn, ctrl->opts->host->nqn) || diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index 850f84d204d0..9c55e4be8a39 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c @@ -1200,6 +1200,7 @@ static void nvme_rdma_error_recovery_work(struct work_struct *work) struct nvme_rdma_ctrl, err_work); nvme_stop_keep_alive(&ctrl->ctrl); + flush_work(&ctrl->ctrl.async_event_work); nvme_rdma_teardown_io_queues(ctrl, false); nvme_start_queues(&ctrl->ctrl); nvme_rdma_teardown_admin_queue(ctrl, false); diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index 4ceb28675fdf..01e24b5703db 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -2096,6 +2096,7 @@ static void nvme_tcp_error_recovery_work(struct work_struct *work) struct nvme_ctrl *ctrl = &tcp_ctrl->ctrl; nvme_stop_keep_alive(ctrl); + flush_work(&ctrl->async_event_work); nvme_tcp_teardown_io_queues(ctrl, false); /* unquiesce to fail fast pending requests */ nvme_start_queues(ctrl); |