Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 869c5548 authored by Adrian Hunter's avatar Adrian Hunter Committed by Jens Axboe
Browse files

mmc: fix use-after-free of struct request



We call mmc_req_is_special() after having processed a request, but
it could be freed after that. Check that ahead of time, and use
the cached value.

Reported-by: default avatarHans de Goede <hdegoede@redhat.com>
Tested-by: default avatarHans de Goede <hdegoede@redhat.com>
Fixes: c2df40df ("drivers: use req op accessor")

Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent f2791e7e
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -2151,6 +2151,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
	struct mmc_card *card = md->queue.card;
	struct mmc_host *host = card->host;
	unsigned long flags;
	bool req_is_special = mmc_req_is_special(req);

	if (req && !mq->mqrq_prev->req)
		/* claim host only for the first request */
@@ -2191,8 +2192,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
	}

out:
	if ((!req && !(mq->flags & MMC_QUEUE_NEW_REQUEST)) ||
	    mmc_req_is_special(req))
	if ((!req && !(mq->flags & MMC_QUEUE_NEW_REQUEST)) || req_is_special)
		/*
		 * Release host when there are no more requests
		 * and after special request(discard, flush) is done.
+3 −1
Original line number Diff line number Diff line
@@ -65,6 +65,8 @@ static int mmc_queue_thread(void *d)
		spin_unlock_irq(q->queue_lock);

		if (req || mq->mqrq_prev->req) {
			bool req_is_special = mmc_req_is_special(req);

			set_current_state(TASK_RUNNING);
			mq->issue_fn(mq, req);
			cond_resched();
@@ -80,7 +82,7 @@ static int mmc_queue_thread(void *d)
			 * has been finished. Do not assign it to previous
			 * request.
			 */
			if (mmc_req_is_special(req))
			if (req_is_special)
				mq->mqrq_cur->req = NULL;

			mq->mqrq_prev->brq.mrq.data = NULL;