From 4a534f93b371e8e6e87ae302757365f0f583e06b Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Sat, 16 Apr 2005 15:25:40 -0700 Subject: [PATCH] [PATCH] possible use-after-free of bio There is a possibility that a bio will be accessed after it has been freed on SCSI. It happens if you submit a bio with BIO_SYNC marked and the auto-unplugging kicks the request_fn, SCSI re-enables interrupts in-between so if the request completes between the add_request() in __make_request() and the bio_sync() call, we could be looking at a dead bio. It's a slim race, but it has been triggered in the Real World. So assign bio_sync() to a local variable instead. Signed-off-by: Jens Axboe Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/ll_rw_blk.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 02242e8ba996..2d6934a02867 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -2559,7 +2559,7 @@ EXPORT_SYMBOL(__blk_attempt_remerge); static int __make_request(request_queue_t *q, struct bio *bio) { struct request *req, *freereq = NULL; - int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, err; + int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, err, sync; sector_t sector; sector = bio->bi_sector; @@ -2567,6 +2567,7 @@ static int __make_request(request_queue_t *q, struct bio *bio) cur_nr_sectors = bio_cur_sectors(bio); rw = bio_data_dir(bio); + sync = bio_sync(bio); /* * low level driver can indicate that it wants pages above a @@ -2698,7 +2699,7 @@ static int __make_request(request_queue_t *q, struct bio *bio) out: if (freereq) __blk_put_request(q, freereq); - if (bio_sync(bio)) + if (sync) __generic_unplug_device(q); spin_unlock_irq(q->queue_lock);