Skip to content

Commit

Permalink
mmc: fix use-after-free of struct request
Browse files Browse the repository at this point in the history
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: Hans de Goede <[email protected]>
Tested-by: Hans de Goede <[email protected]>
Fixes: c2df40d ("drivers: use req op accessor")

Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
ahunter6 authored and axboe committed Aug 25, 2016
1 parent f2791e7 commit 869c554
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 3 deletions.
4 changes: 2 additions & 2 deletions drivers/mmc/card/block.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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.
Expand Down
4 changes: 3 additions & 1 deletion drivers/mmc/card/queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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;
Expand Down

0 comments on commit 869c554

Please sign in to comment.