diff options
author | Jens Axboe <axboe@kernel.dk> | 2018-06-09 06:37:14 -0600 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2018-06-09 06:37:14 -0600 |
commit | 190b02ed79e08983bf62d47c05945c1b06a3d7d5 (patch) | |
tree | 7b1d6db69efaf3ccb7d888d7cdfa1ccb59798178 | |
parent | 77016199f11eacd7b23e2faeb4d0f36166e3530b (diff) | |
download | linux-190b02ed79e08983bf62d47c05945c1b06a3d7d5.tar.gz linux-190b02ed79e08983bf62d47c05945c1b06a3d7d5.tar.bz2 linux-190b02ed79e08983bf62d47c05945c1b06a3d7d5.zip |
block: fix use-after-free in block flush handling
A recent commit reused the original request flags for the flush
queue handling. However, for some of the kick flush cases, the
original request was already completed. This caused a use after
free, if blk-mq wasn't used.
Fixes: 84fca1b0c461 ("block: pass failfast and driver-specific flags to flush requests")
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | block/blk-flush.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/block/blk-flush.c b/block/blk-flush.c index 058abdb50f31..ce41f666de3e 100644 --- a/block/blk-flush.c +++ b/block/blk-flush.c @@ -169,9 +169,11 @@ static bool blk_flush_complete_seq(struct request *rq, struct request_queue *q = rq->q; struct list_head *pending = &fq->flush_queue[fq->flush_pending_idx]; bool queued = false, kicked; + unsigned int cmd_flags; BUG_ON(rq->flush.seq & seq); rq->flush.seq |= seq; + cmd_flags = rq->cmd_flags; if (likely(!error)) seq = blk_flush_cur_seq(rq); @@ -212,7 +214,7 @@ static bool blk_flush_complete_seq(struct request *rq, BUG(); } - kicked = blk_kick_flush(q, fq, rq->cmd_flags); + kicked = blk_kick_flush(q, fq, cmd_flags); return kicked | queued; } |