]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blobdiff - fs/block_dev.c
UBUNTU: [Config] updateconfigs after removing powerpc builds
[mirror_ubuntu-zesty-kernel.git] / fs / block_dev.c
index 3a639adc02b2e4c4ee0e1d222eff8f37abd3668a..c2cac8c005d0863f4187c2f90f47e2ad1f12f1d2 100644 (file)
@@ -1828,6 +1828,20 @@ static int blkdev_open(struct inode * inode, struct file * filp)
        if (bdev == NULL)
                return -ENOMEM;
 
+       /*
+        * A negative i_writecount for bdev->bd_inode means that the bdev
+        * or one of its paritions is mounted in a user namespace. Deny
+        * writing for non-root in this case, otherwise an unprivileged
+        * user can attack the kernel by modifying the backing store of a
+        * mounted filesystem.
+        */
+       if ((filp->f_mode & FMODE_WRITE) &&
+           !file_ns_capable(filp, &init_user_ns, CAP_SYS_ADMIN) &&
+           !atomic_inc_unless_negative(&bdev->bd_inode->i_writecount)) {
+               bdput(bdev);
+               return -EBUSY;
+       }
+
        filp->f_mapping = bdev->bd_inode->i_mapping;
 
        return blkdev_get(bdev, filp->f_mode, filp);
@@ -1929,6 +1943,9 @@ EXPORT_SYMBOL(blkdev_put);
 static int blkdev_close(struct inode * inode, struct file * filp)
 {
        struct block_device *bdev = I_BDEV(bdev_file_inode(filp));
+       if (filp->f_mode & FMODE_WRITE &&
+           !file_ns_capable(filp, &init_user_ns, CAP_SYS_ADMIN))
+               atomic_dec(&bdev->bd_inode->i_writecount);
        blkdev_put(bdev, filp->f_mode);
        return 0;
 }