aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/namespace.c119
1 files changed, 59 insertions, 60 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index 6e283c93b50..9f6005e5586 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1167,19 +1167,19 @@ asmlinkage long sys_oldumount(char __user * name)
1167 1167
1168#endif 1168#endif
1169 1169
1170static int mount_is_safe(struct nameidata *nd) 1170static int mount_is_safe(struct path *path)
1171{ 1171{
1172 if (capable(CAP_SYS_ADMIN)) 1172 if (capable(CAP_SYS_ADMIN))
1173 return 0; 1173 return 0;
1174 return -EPERM; 1174 return -EPERM;
1175#ifdef notyet 1175#ifdef notyet
1176 if (S_ISLNK(nd->path.dentry->d_inode->i_mode)) 1176 if (S_ISLNK(path->dentry->d_inode->i_mode))
1177 return -EPERM; 1177 return -EPERM;
1178 if (nd->path.dentry->d_inode->i_mode & S_ISVTX) { 1178 if (path->dentry->d_inode->i_mode & S_ISVTX) {
1179 if (current->uid != nd->path.dentry->d_inode->i_uid) 1179 if (current->uid != path->dentry->d_inode->i_uid)
1180 return -EPERM; 1180 return -EPERM;
1181 } 1181 }
1182 if (vfs_permission(nd, MAY_WRITE)) 1182 if (inode_permission(path->dentry->d_inode, MAY_WRITE))
1183 return -EPERM; 1183 return -EPERM;
1184 return 0; 1184 return 0;
1185#endif 1185#endif
@@ -1427,9 +1427,9 @@ out_unlock:
1427 * recursively change the type of the mountpoint. 1427 * recursively change the type of the mountpoint.
1428 * noinline this do_mount helper to save do_mount stack space. 1428 * noinline this do_mount helper to save do_mount stack space.
1429 */ 1429 */
1430static noinline int do_change_type(struct nameidata *nd, int flag) 1430static noinline int do_change_type(struct path *path, int flag)
1431{ 1431{
1432 struct vfsmount *m, *mnt = nd->path.mnt; 1432 struct vfsmount *m, *mnt = path->mnt;
1433 int recurse = flag & MS_REC; 1433 int recurse = flag & MS_REC;
1434 int type = flag & ~MS_REC; 1434 int type = flag & ~MS_REC;
1435 int err = 0; 1435 int err = 0;
@@ -1437,7 +1437,7 @@ static noinline int do_change_type(struct nameidata *nd, int flag)
1437 if (!capable(CAP_SYS_ADMIN)) 1437 if (!capable(CAP_SYS_ADMIN))
1438 return -EPERM; 1438 return -EPERM;
1439 1439
1440 if (nd->path.dentry != nd->path.mnt->mnt_root) 1440 if (path->dentry != path->mnt->mnt_root)
1441 return -EINVAL; 1441 return -EINVAL;
1442 1442
1443 down_write(&namespace_sem); 1443 down_write(&namespace_sem);
@@ -1461,38 +1461,38 @@ static noinline int do_change_type(struct nameidata *nd, int flag)
1461 * do loopback mount. 1461 * do loopback mount.
1462 * noinline this do_mount helper to save do_mount stack space. 1462 * noinline this do_mount helper to save do_mount stack space.
1463 */ 1463 */
1464static noinline int do_loopback(struct nameidata *nd, char *old_name, 1464static noinline int do_loopback(struct path *path, char *old_name,
1465 int recurse) 1465 int recurse)
1466{ 1466{
1467 struct nameidata old_nd; 1467 struct path old_path;
1468 struct vfsmount *mnt = NULL; 1468 struct vfsmount *mnt = NULL;
1469 int err = mount_is_safe(nd); 1469 int err = mount_is_safe(path);
1470 if (err) 1470 if (err)
1471 return err; 1471 return err;
1472 if (!old_name || !*old_name) 1472 if (!old_name || !*old_name)
1473 return -EINVAL; 1473 return -EINVAL;
1474 err = path_lookup(old_name, LOOKUP_FOLLOW, &old_nd); 1474 err = kern_path(old_name, LOOKUP_FOLLOW, &old_path);
1475 if (err) 1475 if (err)
1476 return err; 1476 return err;
1477 1477
1478 down_write(&namespace_sem); 1478 down_write(&namespace_sem);
1479 err = -EINVAL; 1479 err = -EINVAL;
1480 if (IS_MNT_UNBINDABLE(old_nd.path.mnt)) 1480 if (IS_MNT_UNBINDABLE(old_path.mnt))
1481 goto out; 1481 goto out;
1482 1482
1483 if (!check_mnt(nd->path.mnt) || !check_mnt(old_nd.path.mnt)) 1483 if (!check_mnt(path->mnt) || !check_mnt(old_path.mnt))
1484 goto out; 1484 goto out;
1485 1485
1486 err = -ENOMEM; 1486 err = -ENOMEM;
1487 if (recurse) 1487 if (recurse)
1488 mnt = copy_tree(old_nd.path.mnt, old_nd.path.dentry, 0); 1488 mnt = copy_tree(old_path.mnt, old_path.dentry, 0);
1489 else 1489 else
1490 mnt = clone_mnt(old_nd.path.mnt, old_nd.path.dentry, 0); 1490 mnt = clone_mnt(old_path.mnt, old_path.dentry, 0);
1491 1491
1492 if (!mnt) 1492 if (!mnt)
1493 goto out; 1493 goto out;
1494 1494
1495 err = graft_tree(mnt, &nd->path); 1495 err = graft_tree(mnt, path);
1496 if (err) { 1496 if (err) {
1497 LIST_HEAD(umount_list); 1497 LIST_HEAD(umount_list);
1498 spin_lock(&vfsmount_lock); 1498 spin_lock(&vfsmount_lock);
@@ -1503,7 +1503,7 @@ static noinline int do_loopback(struct nameidata *nd, char *old_name,
1503 1503
1504out: 1504out:
1505 up_write(&namespace_sem); 1505 up_write(&namespace_sem);
1506 path_put(&old_nd.path); 1506 path_put(&old_path);
1507 return err; 1507 return err;
1508} 1508}
1509 1509
@@ -1530,31 +1530,31 @@ static int change_mount_flags(struct vfsmount *mnt, int ms_flags)
1530 * on it - tough luck. 1530 * on it - tough luck.
1531 * noinline this do_mount helper to save do_mount stack space. 1531 * noinline this do_mount helper to save do_mount stack space.
1532 */ 1532 */
1533static noinline int do_remount(struct nameidata *nd, int flags, int mnt_flags, 1533static noinline int do_remount(struct path *path, int flags, int mnt_flags,
1534 void *data) 1534 void *data)
1535{ 1535{
1536 int err; 1536 int err;
1537 struct super_block *sb = nd->path.mnt->mnt_sb; 1537 struct super_block *sb = path->mnt->mnt_sb;
1538 1538
1539 if (!capable(CAP_SYS_ADMIN)) 1539 if (!capable(CAP_SYS_ADMIN))
1540 return -EPERM; 1540 return -EPERM;
1541 1541
1542 if (!check_mnt(nd->path.mnt)) 1542 if (!check_mnt(path->mnt))
1543 return -EINVAL; 1543 return -EINVAL;
1544 1544
1545 if (nd->path.dentry != nd->path.mnt->mnt_root) 1545 if (path->dentry != path->mnt->mnt_root)
1546 return -EINVAL; 1546 return -EINVAL;
1547 1547
1548 down_write(&sb->s_umount); 1548 down_write(&sb->s_umount);
1549 if (flags & MS_BIND) 1549 if (flags & MS_BIND)
1550 err = change_mount_flags(nd->path.mnt, flags); 1550 err = change_mount_flags(path->mnt, flags);
1551 else 1551 else
1552 err = do_remount_sb(sb, flags, data, 0); 1552 err = do_remount_sb(sb, flags, data, 0);
1553 if (!err) 1553 if (!err)
1554 nd->path.mnt->mnt_flags = mnt_flags; 1554 path->mnt->mnt_flags = mnt_flags;
1555 up_write(&sb->s_umount); 1555 up_write(&sb->s_umount);
1556 if (!err) 1556 if (!err)
1557 security_sb_post_remount(nd->path.mnt, flags, data); 1557 security_sb_post_remount(path->mnt, flags, data);
1558 return err; 1558 return err;
1559} 1559}
1560 1560
@@ -1571,78 +1571,77 @@ static inline int tree_contains_unbindable(struct vfsmount *mnt)
1571/* 1571/*
1572 * noinline this do_mount helper to save do_mount stack space. 1572 * noinline this do_mount helper to save do_mount stack space.
1573 */ 1573 */
1574static noinline int do_move_mount(struct nameidata *nd, char *old_name) 1574static noinline int do_move_mount(struct path *path, char *old_name)
1575{ 1575{
1576 struct nameidata old_nd; 1576 struct path old_path, parent_path;
1577 struct path parent_path;
1578 struct vfsmount *p; 1577 struct vfsmount *p;
1579 int err = 0; 1578 int err = 0;
1580 if (!capable(CAP_SYS_ADMIN)) 1579 if (!capable(CAP_SYS_ADMIN))
1581 return -EPERM; 1580 return -EPERM;
1582 if (!old_name || !*old_name) 1581 if (!old_name || !*old_name)
1583 return -EINVAL; 1582 return -EINVAL;
1584 err = path_lookup(old_name, LOOKUP_FOLLOW, &old_nd); 1583 err = kern_path(old_name, LOOKUP_FOLLOW, &old_path);
1585 if (err) 1584 if (err)
1586 return err; 1585 return err;
1587 1586
1588 down_write(&namespace_sem); 1587 down_write(&namespace_sem);
1589 while (d_mountpoint(nd->path.dentry) && 1588 while (d_mountpoint(path->dentry) &&
1590 follow_down(&nd->path.mnt, &nd->path.dentry)) 1589 follow_down(&path->mnt, &path->dentry))
1591 ; 1590 ;
1592 err = -EINVAL; 1591 err = -EINVAL;
1593 if (!check_mnt(nd->path.mnt) || !check_mnt(old_nd.path.mnt)) 1592 if (!check_mnt(path->mnt) || !check_mnt(old_path.mnt))
1594 goto out; 1593 goto out;
1595 1594
1596 err = -ENOENT; 1595 err = -ENOENT;
1597 mutex_lock(&nd->path.dentry->d_inode->i_mutex); 1596 mutex_lock(&path->dentry->d_inode->i_mutex);
1598 if (IS_DEADDIR(nd->path.dentry->d_inode)) 1597 if (IS_DEADDIR(path->dentry->d_inode))
1599 goto out1; 1598 goto out1;
1600 1599
1601 if (!IS_ROOT(nd->path.dentry) && d_unhashed(nd->path.dentry)) 1600 if (!IS_ROOT(path->dentry) && d_unhashed(path->dentry))
1602 goto out1; 1601 goto out1;
1603 1602
1604 err = -EINVAL; 1603 err = -EINVAL;
1605 if (old_nd.path.dentry != old_nd.path.mnt->mnt_root) 1604 if (old_path.dentry != old_path.mnt->mnt_root)
1606 goto out1; 1605 goto out1;
1607 1606
1608 if (old_nd.path.mnt == old_nd.path.mnt->mnt_parent) 1607 if (old_path.mnt == old_path.mnt->mnt_parent)
1609 goto out1; 1608 goto out1;
1610 1609
1611 if (S_ISDIR(nd->path.dentry->d_inode->i_mode) != 1610 if (S_ISDIR(path->dentry->d_inode->i_mode) !=
1612 S_ISDIR(old_nd.path.dentry->d_inode->i_mode)) 1611 S_ISDIR(old_path.dentry->d_inode->i_mode))
1613 goto out1; 1612 goto out1;
1614 /* 1613 /*
1615 * Don't move a mount residing in a shared parent. 1614 * Don't move a mount residing in a shared parent.
1616 */ 1615 */
1617 if (old_nd.path.mnt->mnt_parent && 1616 if (old_path.mnt->mnt_parent &&
1618 IS_MNT_SHARED(old_nd.path.mnt->mnt_parent)) 1617 IS_MNT_SHARED(old_path.mnt->mnt_parent))
1619 goto out1; 1618 goto out1;
1620 /* 1619 /*
1621 * Don't move a mount tree containing unbindable mounts to a destination 1620 * Don't move a mount tree containing unbindable mounts to a destination
1622 * mount which is shared. 1621 * mount which is shared.
1623 */ 1622 */
1624 if (IS_MNT_SHARED(nd->path.mnt) && 1623 if (IS_MNT_SHARED(path->mnt) &&
1625 tree_contains_unbindable(old_nd.path.mnt)) 1624 tree_contains_unbindable(old_path.mnt))
1626 goto out1; 1625 goto out1;
1627 err = -ELOOP; 1626 err = -ELOOP;
1628 for (p = nd->path.mnt; p->mnt_parent != p; p = p->mnt_parent) 1627 for (p = path->mnt; p->mnt_parent != p; p = p->mnt_parent)
1629 if (p == old_nd.path.mnt) 1628 if (p == old_path.mnt)
1630 goto out1; 1629 goto out1;
1631 1630
1632 err = attach_recursive_mnt(old_nd.path.mnt, &nd->path, &parent_path); 1631 err = attach_recursive_mnt(old_path.mnt, path, &parent_path);
1633 if (err) 1632 if (err)
1634 goto out1; 1633 goto out1;
1635 1634
1636 /* if the mount is moved, it should no longer be expire 1635 /* if the mount is moved, it should no longer be expire
1637 * automatically */ 1636 * automatically */
1638 list_del_init(&old_nd.path.mnt->mnt_expire); 1637 list_del_init(&old_path.mnt->mnt_expire);
1639out1: 1638out1:
1640 mutex_unlock(&nd->path.dentry->d_inode->i_mutex); 1639 mutex_unlock(&path->dentry->d_inode->i_mutex);
1641out: 1640out:
1642 up_write(&namespace_sem); 1641 up_write(&namespace_sem);
1643 if (!err) 1642 if (!err)
1644 path_put(&parent_path); 1643 path_put(&parent_path);
1645 path_put(&old_nd.path); 1644 path_put(&old_path);
1646 return err; 1645 return err;
1647} 1646}
1648 1647
@@ -1651,7 +1650,7 @@ out:
1651 * namespace's tree 1650 * namespace's tree
1652 * noinline this do_mount helper to save do_mount stack space. 1651 * noinline this do_mount helper to save do_mount stack space.
1653 */ 1652 */
1654static noinline int do_new_mount(struct nameidata *nd, char *type, int flags, 1653static noinline int do_new_mount(struct path *path, char *type, int flags,
1655 int mnt_flags, char *name, void *data) 1654 int mnt_flags, char *name, void *data)
1656{ 1655{
1657 struct vfsmount *mnt; 1656 struct vfsmount *mnt;
@@ -1667,7 +1666,7 @@ static noinline int do_new_mount(struct nameidata *nd, char *type, int flags,
1667 if (IS_ERR(mnt)) 1666 if (IS_ERR(mnt))
1668 return PTR_ERR(mnt); 1667 return PTR_ERR(mnt);
1669 1668
1670 return do_add_mount(mnt, &nd->path, mnt_flags, NULL); 1669 return do_add_mount(mnt, path, mnt_flags, NULL);
1671} 1670}
1672 1671
1673/* 1672/*
@@ -1902,7 +1901,7 @@ int copy_mount_options(const void __user * data, unsigned long *where)
1902long do_mount(char *dev_name, char *dir_name, char *type_page, 1901long do_mount(char *dev_name, char *dir_name, char *type_page,
1903 unsigned long flags, void *data_page) 1902 unsigned long flags, void *data_page)
1904{ 1903{
1905 struct nameidata nd; 1904 struct path path;
1906 int retval = 0; 1905 int retval = 0;
1907 int mnt_flags = 0; 1906 int mnt_flags = 0;
1908 1907
@@ -1940,29 +1939,29 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
1940 MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT); 1939 MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT);
1941 1940
1942 /* ... and get the mountpoint */ 1941 /* ... and get the mountpoint */
1943 retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd); 1942 retval = kern_path(dir_name, LOOKUP_FOLLOW, &path);
1944 if (retval) 1943 if (retval)
1945 return retval; 1944 return retval;
1946 1945
1947 retval = security_sb_mount(dev_name, &nd.path, 1946 retval = security_sb_mount(dev_name, &path,
1948 type_page, flags, data_page); 1947 type_page, flags, data_page);
1949 if (retval) 1948 if (retval)
1950 goto dput_out; 1949 goto dput_out;
1951 1950
1952 if (flags & MS_REMOUNT) 1951 if (flags & MS_REMOUNT)
1953 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags, 1952 retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags,
1954 data_page); 1953 data_page);
1955 else if (flags & MS_BIND) 1954 else if (flags & MS_BIND)
1956 retval = do_loopback(&nd, dev_name, flags & MS_REC); 1955 retval = do_loopback(&path, dev_name, flags & MS_REC);
1957 else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) 1956 else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
1958 retval = do_change_type(&nd, flags); 1957 retval = do_change_type(&path, flags);
1959 else if (flags & MS_MOVE) 1958 else if (flags & MS_MOVE)
1960 retval = do_move_mount(&nd, dev_name); 1959 retval = do_move_mount(&path, dev_name);
1961 else 1960 else
1962 retval = do_new_mount(&nd, type_page, flags, mnt_flags, 1961 retval = do_new_mount(&path, type_page, flags, mnt_flags,
1963 dev_name, data_page); 1962 dev_name, data_page);
1964dput_out: 1963dput_out:
1965 path_put(&nd.path); 1964 path_put(&path);
1966 return retval; 1965 return retval;
1967} 1966}
1968 1967