Skip to content

Commit f5c84ef

Browse files
Lizhi Xuaxboe
Lizhi Xu
authored andcommitted
loop: Add sanity check for read/write_iter
Some file systems do not support read_iter/write_iter, such as selinuxfs in this issue. So before calling them, first confirm that the interface is supported and then call it. It is releavant in that vfs_iter_read/write have the check, and removal of their used caused szybot to be able to hit this issue. Fixes: f2fed44 ("loop: stop using vfs_iter__{read,write} for buffered I/O") Reported-by: [email protected] Closes: https://syzkaller.appspot.com/bug?extid=6af973a3b8dfd2faefdc Signed-off-by: Lizhi Xu <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent 6d732e8 commit f5c84ef

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

drivers/block/loop.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,17 @@ static void loop_assign_backing_file(struct loop_device *lo, struct file *file)
505505
lo->lo_min_dio_size = loop_query_min_dio_size(lo);
506506
}
507507

508+
static int loop_check_backing_file(struct file *file)
509+
{
510+
if (!file->f_op->read_iter)
511+
return -EINVAL;
512+
513+
if ((file->f_mode & FMODE_WRITE) && !file->f_op->write_iter)
514+
return -EINVAL;
515+
516+
return 0;
517+
}
518+
508519
/*
509520
* loop_change_fd switched the backing store of a loopback device to
510521
* a new file. This is useful for operating system installers to free up
@@ -526,6 +537,10 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
526537
if (!file)
527538
return -EBADF;
528539

540+
error = loop_check_backing_file(file);
541+
if (error)
542+
return error;
543+
529544
/* suppress uevents while reconfiguring the device */
530545
dev_set_uevent_suppress(disk_to_dev(lo->lo_disk), 1);
531546

@@ -963,6 +978,14 @@ static int loop_configure(struct loop_device *lo, blk_mode_t mode,
963978

964979
if (!file)
965980
return -EBADF;
981+
982+
if ((mode & BLK_OPEN_WRITE) && !file->f_op->write_iter)
983+
return -EINVAL;
984+
985+
error = loop_check_backing_file(file);
986+
if (error)
987+
return error;
988+
966989
is_loop = is_loop_device(file);
967990

968991
/* This is safe, since we have a reference from open(). */

0 commit comments

Comments
 (0)