On Mon, 2018-07-16 at 09:36 +0200, Greg Kroah-Hartman wrote:
4.4-stable review patch. If anyone has any objections, please let me know.
From: Theodore Ts'o tytso@mit.edu
commit d2ac838e4cd7e5e9891ecc094d626734b0245c99 upstream.
Refactor the validation code used in LOOP_SET_FD so it is also used in LOOP_CHANGE_FD. Otherwise it is possible to construct a set of loop devices that all refer to each other. This can lead to a infinite loop in starting with "while (is_loop_device(f)) .." in loop_set_fd().
Fix this by refactoring out the validation code and using it for LOOP_CHANGE_FD as well as LOOP_SET_FD.
[...]
+static int loop_validate_file(struct file *file, struct block_device *bdev) +{
- struct inode *inode = file->f_mapping->host;
- struct file *f = file;
- /* Avoid recursion */
- while (is_loop_device(f)) {
struct loop_device *l;
if (f->f_mapping->host->i_bdev == bdev)
return -EBADF;
l = f->f_mapping->host->i_bdev->bd_disk->private_data;
if (l->lo_state == Lo_unbound) {
return -EINVAL;
}
f = l->lo_backing_file;
This looks racy; I don't see anything that prevents a lower loop device from being reconfigured while this walks down the device stack.
(But this isn't a new problem.)
Ben.
- }
- if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))
return -EINVAL;
- return 0;
+}
[...]