mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git
synced 2026-05-02 10:07:26 -04:00
nvme: code command_id with a genctr for use-after-free validation
We cannot detect a (perhaps buggy) controller that is sending us a completion for a request that was already completed (for example sending a completion twice), this phenomenon was seen in the wild a few times. So to protect against this, we use the upper 4 msbits of the nvme sqe command_id to use as a 4-bit generation counter and verify it matches the existing request generation that is incrementing on every execution. The 16-bit command_id structure now is constructed by: | xxxx | xxxxxxxxxxxx | gen request tag This means that we are giving up some possible queue depth as 12 bits allow for a maximum queue depth of 4095 instead of 65536, however we never create such long queues anyways so no real harm done. Suggested-by: Keith Busch <kbusch@kernel.org> Signed-off-by: Sagi Grimberg <sagi@grimberg.me> Acked-by: Keith Busch <kbusch@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Daniel Wagner <dwagner@suse.de> Tested-by: Daniel Wagner <dwagner@suse.de> Signed-off-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
committed by
Christoph Hellwig
parent
3b01a9d0ca
commit
e7006de6c2
@@ -107,10 +107,10 @@ static void nvme_loop_queue_response(struct nvmet_req *req)
|
||||
} else {
|
||||
struct request *rq;
|
||||
|
||||
rq = blk_mq_tag_to_rq(nvme_loop_tagset(queue), cqe->command_id);
|
||||
rq = nvme_find_rq(nvme_loop_tagset(queue), cqe->command_id);
|
||||
if (!rq) {
|
||||
dev_err(queue->ctrl->ctrl.device,
|
||||
"tag 0x%x on queue %d not found\n",
|
||||
"got bad command_id %#x on queue %d\n",
|
||||
cqe->command_id, nvme_loop_queue_idx(queue));
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user