diff options
author | Jens Axboe <axboe@fb.com> | 2017-02-24 15:19:32 -0500 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2017-02-24 15:19:32 -0500 |
commit | 61febef40bfe8ab68259d8545257686e8a0d91d1 (patch) | |
tree | 94d52c7e6d62b1f7381fc615c8964e0751e7ca08 | |
parent | d38d35155514ceef5efb79f6d5b4f0f1638da5b4 (diff) |
dm-rq: don't dereference request payload after ending request
Bart reported a case where dm would crash with use-after-free
poison. This is due to dm_softirq_done() accessing memory
associated with a request after calling end_request on it.
This is most visible on !blk-mq, since we free the memory
immediately for that case.
Reported-by: Bart Van Assche <bart.vanassche@sandisk.com>
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Fixes: eb8db831be80 ("dm: always defer request allocation to the owner of the request_queue")
Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r-- | drivers/md/dm-rq.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c index 67d76f21fecd..28955b94d2b2 100644 --- a/drivers/md/dm-rq.c +++ b/drivers/md/dm-rq.c | |||
@@ -328,13 +328,15 @@ static void dm_softirq_done(struct request *rq) | |||
328 | int rw; | 328 | int rw; |
329 | 329 | ||
330 | if (!clone) { | 330 | if (!clone) { |
331 | rq_end_stats(tio->md, rq); | 331 | struct mapped_device *md = tio->md; |
332 | |||
333 | rq_end_stats(md, rq); | ||
332 | rw = rq_data_dir(rq); | 334 | rw = rq_data_dir(rq); |
333 | if (!rq->q->mq_ops) | 335 | if (!rq->q->mq_ops) |
334 | blk_end_request_all(rq, tio->error); | 336 | blk_end_request_all(rq, tio->error); |
335 | else | 337 | else |
336 | blk_mq_end_request(rq, tio->error); | 338 | blk_mq_end_request(rq, tio->error); |
337 | rq_completed(tio->md, rw, false); | 339 | rq_completed(md, rw, false); |
338 | return; | 340 | return; |
339 | } | 341 | } |
340 | 342 | ||