fsg_lun_open() takes any regular file as the backing file of a LUN. The file-storage kthread then reads and writes it with kernel_read() and kernel_write() on behalf of the USB host. With a procfs or sysfs file behind a LUN the host gets to read and write kernel interfaces with kernel credentials. Refuse files on pseudo filesystems just like loop does by switching to file_check_backing(). The helper also does the file type and readability checks. So the messages for an unsuitable backing file become one. It looks at the inode of the file instead of the host of ->f_mapping. For regular files and block devices both have the same type. It also wants ->read_iter() where FMODE_CAN_READ was enough so far. But kernel_read() never worked without ->read_iter() anyway. Signed-off-by: Christian Brauner (Amutable) --- drivers/usb/gadget/function/storage_common.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/usb/gadget/function/storage_common.c b/drivers/usb/gadget/function/storage_common.c index 75831f2c7abeb..af0c37a9fe029 100644 --- a/drivers/usb/gadget/function/storage_common.c +++ b/drivers/usb/gadget/function/storage_common.c @@ -205,23 +205,18 @@ int fsg_lun_open(struct fsg_lun *curlun, const char *filename) if (!(filp->f_mode & FMODE_WRITE)) ro = 1; - inode = filp->f_mapping->host; - if ((!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))) { - LINFO(curlun, "invalid file type: %s\n", filename); - goto out; - } - /* * If we can't read the file, it's no good. * If we can't write the file, use it read-only. */ - if (!(filp->f_mode & FMODE_CAN_READ)) { - LINFO(curlun, "file not readable: %s\n", filename); + if (file_check_backing(filp, FMODE_READ, S_IFBLK)) { + LINFO(curlun, "invalid backing file: %s\n", filename); goto out; } if (!(filp->f_mode & FMODE_CAN_WRITE)) ro = 1; + inode = filp->f_mapping->host; size = i_size_read(inode); if (size < 0) { LINFO(curlun, "unable to find file size: %s\n", filename); -- 2.53.0