Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mount: consolidate permission checks

... and ask for global CAP_SYS_ADMIN only for superblock-level remounts

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Al Viro 57eccb83 9b40bc90

+7 -33
+7 -33
fs/namespace.c
··· 1300 1300 1301 1301 #endif 1302 1302 1303 - static int mount_is_safe(struct path *path) 1304 - { 1305 - if (may_mount()) 1306 - return 0; 1307 - return -EPERM; 1308 - #ifdef notyet 1309 - if (S_ISLNK(path->dentry->d_inode->i_mode)) 1310 - return -EPERM; 1311 - if (path->dentry->d_inode->i_mode & S_ISVTX) { 1312 - if (current_uid() != path->dentry->d_inode->i_uid) 1313 - return -EPERM; 1314 - } 1315 - if (inode_permission(path->dentry->d_inode, MAY_WRITE)) 1316 - return -EPERM; 1317 - return 0; 1318 - #endif 1319 - } 1320 - 1321 1303 static bool mnt_ns_loop(struct path *path) 1322 1304 { 1323 1305 /* Could bind mounting the mount namespace inode cause a ··· 1622 1640 int type; 1623 1641 int err = 0; 1624 1642 1625 - if (!may_mount()) 1626 - return -EPERM; 1627 - 1628 1643 if (path->dentry != path->mnt->mnt_root) 1629 1644 return -EINVAL; 1630 1645 ··· 1655 1676 LIST_HEAD(umount_list); 1656 1677 struct path old_path; 1657 1678 struct mount *mnt = NULL, *old; 1658 - int err = mount_is_safe(path); 1659 - if (err) 1660 - return err; 1679 + int err; 1661 1680 if (!old_name || !*old_name) 1662 1681 return -EINVAL; 1663 1682 err = kern_path(old_name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &old_path); ··· 1732 1755 struct super_block *sb = path->mnt->mnt_sb; 1733 1756 struct mount *mnt = real_mount(path->mnt); 1734 1757 1735 - if (!capable(CAP_SYS_ADMIN)) 1736 - return -EPERM; 1737 - 1738 1758 if (!check_mnt(mnt)) 1739 1759 return -EINVAL; 1740 1760 ··· 1745 1771 down_write(&sb->s_umount); 1746 1772 if (flags & MS_BIND) 1747 1773 err = change_mount_flags(path->mnt, flags); 1774 + else if (!capable(CAP_SYS_ADMIN)) 1775 + err = -EPERM; 1748 1776 else 1749 1777 err = do_remount_sb(sb, flags, data, 0); 1750 1778 if (!err) { ··· 1779 1803 struct path old_path, parent_path; 1780 1804 struct mount *p; 1781 1805 struct mount *old; 1782 - int err = 0; 1783 - if (!may_mount()) 1784 - return -EPERM; 1806 + int err; 1785 1807 if (!old_name || !*old_name) 1786 1808 return -EINVAL; 1787 1809 err = kern_path(old_name, LOOKUP_FOLLOW, &old_path); ··· 1920 1946 1921 1947 if (!fstype) 1922 1948 return -EINVAL; 1923 - 1924 - if (!may_mount()) 1925 - return -EPERM; 1926 1949 1927 1950 type = get_fs_type(fstype); 1928 1951 if (!type) ··· 2233 2262 type_page, flags, data_page); 2234 2263 if (retval) 2235 2264 goto dput_out; 2265 + 2266 + if (!may_mount()) 2267 + return -EPERM; 2236 2268 2237 2269 /* Default to relatime unless overriden */ 2238 2270 if (!(flags & MS_NOATIME))