summaryrefslogtreecommitdiff
path: root/drivers/block/loop.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-01-05 16:26:00 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-02-03 17:38:47 +0100
commitd5e06a1867210049bbfe27864ee0a40cfd9b1e9b (patch)
treeafc4d262e05b9fc399d9326eba96040150aaadb2 /drivers/block/loop.c
parentd383a4277b75f3305d78006bb8de673cd17d04a5 (diff)
loop: fix concurrent lo_open/lo_release
commit ae6650163c66a7eff1acd6eb8b0f752dcfa8eba5 upstream. 范龙飞 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> Cc: Ben Hutchings <ben.hutchings@codethink.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
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 85de67334695..a2a0dce5114e 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1576,9 +1576,8 @@ out:
return err;
}
-static void lo_release(struct gendisk *disk, fmode_t mode)
+static void __lo_release(struct loop_device *lo)
{
- struct loop_device *lo = disk->private_data;
int err;
if (atomic_dec_return(&lo->lo_refcnt))
@@ -1605,6 +1604,13 @@ static void lo_release(struct gendisk *disk, fmode_t mode)
mutex_unlock(&lo->lo_ctl_mutex);
}
+static void lo_release(struct gendisk *disk, fmode_t mode)
+{
+ mutex_lock(&loop_index_mutex);
+ __lo_release(disk->private_data);
+ mutex_unlock(&loop_index_mutex);
+}
+
static const struct block_device_operations lo_fops = {
.owner = THIS_MODULE,
.open = lo_open,