summaryrefslogtreecommitdiffstats
path: root/drivers/block/loop.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-01-05 19:26:00 -0500
committerJens Axboe <axboe@kernel.dk>2018-01-06 11:32:07 -0500
commitae6650163c66a7eff1acd6eb8b0f752dcfa8eba5 (patch)
treef581ac94d3f2c1e2059e04c392788b0ad4119ba8 /drivers/block/loop.c
parentcbf3a95924d515c1883aec2322fec277e4726134 (diff)
loop: fix concurrent lo_open/lo_release
范龙飞 reports that KASAN can report a use-after-free in __lock_acquire. The reason is due to insufficient serialization in lo_release(), which will continue to use the loop device even after it has decremented the lo_refcnt to zero. In the meantime, another process can come in, open the loop device again as it is being shut down. Confusion ensues. Reported-by: 范龙飞 <long7573@126.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/block/loop.c')
-rw-r--r--drivers/block/loop.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index bc8e61506968..d5fe720cf149 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1581,9 +1581,8 @@ out:
1581 return err; 1581 return err;
1582} 1582}
1583 1583
1584static void lo_release(struct gendisk *disk, fmode_t mode) 1584static void __lo_release(struct loop_device *lo)
1585{ 1585{
1586 struct loop_device *lo = disk->private_data;
1587 int err; 1586 int err;
1588 1587
1589 if (atomic_dec_return(&lo->lo_refcnt)) 1588 if (atomic_dec_return(&lo->lo_refcnt))
@@ -1610,6 +1609,13 @@ static void lo_release(struct gendisk *disk, fmode_t mode)
1610 mutex_unlock(&lo->lo_ctl_mutex); 1609 mutex_unlock(&lo->lo_ctl_mutex);
1611} 1610}
1612 1611
1612static void lo_release(struct gendisk *disk, fmode_t mode)
1613{
1614 mutex_lock(&loop_index_mutex);
1615 __lo_release(disk->private_data);
1616 mutex_unlock(&loop_index_mutex);
1617}
1618
1613static const struct block_device_operations lo_fops = { 1619static const struct block_device_operations lo_fops = {
1614 .owner = THIS_MODULE, 1620 .owner = THIS_MODULE,
1615 .open = lo_open, 1621 .open = lo_open,