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@xxxxxxx> > > 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; > +} [...] -- Ben Hutchings, Software Developer Codethink Ltd https://www.codethink.co.uk/ Dale House, 35 Dale Street Manchester, M1 2HF, United Kingdom