[PATCH 3/3] nvme: code command_id with a genctr for use-after-free validation
Keith Busch
kbusch at kernel.org
Mon May 17 12:04:19 PDT 2021
On Mon, May 17, 2021 at 10:59:55AM -0700, Sagi Grimberg wrote:
> +static inline struct request *nvme_find_rq(struct blk_mq_tags *tags,
> + u16 command_id)
> +{
> + u8 genctr = nvme_genctr_from_cid(command_id);
> + u16 tag = nvme_tag_from_cid(command_id);
> + struct request *rq;
> +
> + rq = blk_mq_tag_to_rq(tags, tag);
> + if (unlikely(!rq)) {
> + pr_err("could not locate request for tag %#x\n",
> + tag);
> + return NULL;
> + }
> + if (unlikely(nvme_genctr_mask(nvme_req(rq)->genctr) != genctr)) {
> + dev_err(nvme_req(rq)->ctrl->device,
> + "request %#x genctr mismatch (got %#x expected %#x)\n",
> + tag, genctr, nvme_req(rq)->genctr);
> + return NULL;
> + }
Should we also check for blk_mq_request_started(rq) here? It doesn't look
like the genctr is sufficient to detect a double completion of the same
command_id if the driver hasn't had a chance to advance the genctr for a
new request.
> + return rq;
> +}
More information about the Linux-nvme
mailing list