diff options
author | Bart Van Assche <bvanassche@acm.org> | 2022-08-13 00:03:17 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2022-09-15 12:30:02 +0300 |
commit | ebf46da50beb78066674354ad650606a467e33fa (patch) | |
tree | c1efe8a6c9e9dca30cb6563305bf1046259bec71 /drivers/nvme | |
parent | 58acd2ebae034db3bacf38708f508fbd12ae2e54 (diff) | |
download | linux-ebf46da50beb78066674354ad650606a467e33fa.tar.xz |
nvmet: fix a use-after-free
commit 6a02a61e81c231cc5c680c5dbf8665275147ac52 upstream.
Fix the following use-after-free complaint triggered by blktests nvme/004:
BUG: KASAN: user-memory-access in blk_mq_complete_request_remote+0xac/0x350
Read of size 4 at addr 0000607bd1835943 by task kworker/13:1/460
Workqueue: nvmet-wq nvme_loop_execute_work [nvme_loop]
Call Trace:
show_stack+0x52/0x58
dump_stack_lvl+0x49/0x5e
print_report.cold+0x36/0x1e2
kasan_report+0xb9/0xf0
__asan_load4+0x6b/0x80
blk_mq_complete_request_remote+0xac/0x350
nvme_loop_queue_response+0x1df/0x275 [nvme_loop]
__nvmet_req_complete+0x132/0x4f0 [nvmet]
nvmet_req_complete+0x15/0x40 [nvmet]
nvmet_execute_io_connect+0x18a/0x1f0 [nvmet]
nvme_loop_execute_work+0x20/0x30 [nvme_loop]
process_one_work+0x56e/0xa70
worker_thread+0x2d1/0x640
kthread+0x183/0x1c0
ret_from_fork+0x1f/0x30
Cc: stable@vger.kernel.org
Fixes: a07b4970f464 ("nvmet: add a generic NVMe target")
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/nvme')
-rw-r--r-- | drivers/nvme/target/core.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index a8dafe8670f2..0a0c1d956c73 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -736,6 +736,8 @@ static void nvmet_set_error(struct nvmet_req *req, u16 status) static void __nvmet_req_complete(struct nvmet_req *req, u16 status) { + struct nvmet_ns *ns = req->ns; + if (!req->sq->sqhd_disabled) nvmet_update_sq_head(req); req->cqe->sq_id = cpu_to_le16(req->sq->qid); @@ -746,9 +748,9 @@ static void __nvmet_req_complete(struct nvmet_req *req, u16 status) trace_nvmet_req_complete(req); - if (req->ns) - nvmet_put_namespace(req->ns); req->ops->queue_response(req); + if (ns) + nvmet_put_namespace(ns); } void nvmet_req_complete(struct nvmet_req *req, u16 status) |