aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namespace.c')
-rw-r--r--fs/namespace.c41
1 files changed, 16 insertions, 25 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index fd999cab7b57..b696e3a0d18f 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -377,6 +377,10 @@ static int show_vfsmnt(struct seq_file *m, void *v)
377 seq_path(m, mnt, mnt->mnt_root, " \t\n\\"); 377 seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
378 seq_putc(m, ' '); 378 seq_putc(m, ' ');
379 mangle(m, mnt->mnt_sb->s_type->name); 379 mangle(m, mnt->mnt_sb->s_type->name);
380 if (mnt->mnt_sb->s_subtype && mnt->mnt_sb->s_subtype[0]) {
381 seq_putc(m, '.');
382 mangle(m, mnt->mnt_sb->s_subtype);
383 }
380 seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw"); 384 seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw");
381 for (fs_infop = fs_info; fs_infop->flag; fs_infop++) { 385 for (fs_infop = fs_info; fs_infop->flag; fs_infop++) {
382 if (mnt->mnt_sb->s_flags & fs_infop->flag) 386 if (mnt->mnt_sb->s_flags & fs_infop->flag)
@@ -495,7 +499,7 @@ void release_mounts(struct list_head *head)
495{ 499{
496 struct vfsmount *mnt; 500 struct vfsmount *mnt;
497 while (!list_empty(head)) { 501 while (!list_empty(head)) {
498 mnt = list_entry(head->next, struct vfsmount, mnt_hash); 502 mnt = list_first_entry(head, struct vfsmount, mnt_hash);
499 list_del_init(&mnt->mnt_hash); 503 list_del_init(&mnt->mnt_hash);
500 if (mnt->mnt_parent != mnt) { 504 if (mnt->mnt_parent != mnt) {
501 struct dentry *dentry; 505 struct dentry *dentry;
@@ -882,6 +886,9 @@ static int do_change_type(struct nameidata *nd, int flag)
882 int recurse = flag & MS_REC; 886 int recurse = flag & MS_REC;
883 int type = flag & ~MS_REC; 887 int type = flag & ~MS_REC;
884 888
889 if (!capable(CAP_SYS_ADMIN))
890 return -EPERM;
891
885 if (nd->dentry != nd->mnt->mnt_root) 892 if (nd->dentry != nd->mnt->mnt_root)
886 return -EINVAL; 893 return -EINVAL;
887 894
@@ -1173,7 +1180,7 @@ static void expire_mount_list(struct list_head *graveyard, struct list_head *mou
1173 1180
1174 while (!list_empty(graveyard)) { 1181 while (!list_empty(graveyard)) {
1175 LIST_HEAD(umounts); 1182 LIST_HEAD(umounts);
1176 mnt = list_entry(graveyard->next, struct vfsmount, mnt_expire); 1183 mnt = list_first_entry(graveyard, struct vfsmount, mnt_expire);
1177 list_del_init(&mnt->mnt_expire); 1184 list_del_init(&mnt->mnt_expire);
1178 1185
1179 /* don't do anything if the namespace is dead - all the 1186 /* don't do anything if the namespace is dead - all the
@@ -1441,10 +1448,9 @@ dput_out:
1441 * Allocate a new namespace structure and populate it with contents 1448 * Allocate a new namespace structure and populate it with contents
1442 * copied from the namespace of the passed in task structure. 1449 * copied from the namespace of the passed in task structure.
1443 */ 1450 */
1444struct mnt_namespace *dup_mnt_ns(struct task_struct *tsk, 1451static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
1445 struct fs_struct *fs) 1452 struct fs_struct *fs)
1446{ 1453{
1447 struct mnt_namespace *mnt_ns = tsk->nsproxy->mnt_ns;
1448 struct mnt_namespace *new_ns; 1454 struct mnt_namespace *new_ns;
1449 struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL; 1455 struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL;
1450 struct vfsmount *p, *q; 1456 struct vfsmount *p, *q;
@@ -1509,36 +1515,21 @@ struct mnt_namespace *dup_mnt_ns(struct task_struct *tsk,
1509 return new_ns; 1515 return new_ns;
1510} 1516}
1511 1517
1512int copy_mnt_ns(int flags, struct task_struct *tsk) 1518struct mnt_namespace *copy_mnt_ns(int flags, struct mnt_namespace *ns,
1519 struct fs_struct *new_fs)
1513{ 1520{
1514 struct mnt_namespace *ns = tsk->nsproxy->mnt_ns;
1515 struct mnt_namespace *new_ns; 1521 struct mnt_namespace *new_ns;
1516 int err = 0;
1517
1518 if (!ns)
1519 return 0;
1520 1522
1523 BUG_ON(!ns);
1521 get_mnt_ns(ns); 1524 get_mnt_ns(ns);
1522 1525
1523 if (!(flags & CLONE_NEWNS)) 1526 if (!(flags & CLONE_NEWNS))
1524 return 0; 1527 return ns;
1525 1528
1526 if (!capable(CAP_SYS_ADMIN)) { 1529 new_ns = dup_mnt_ns(ns, new_fs);
1527 err = -EPERM;
1528 goto out;
1529 }
1530
1531 new_ns = dup_mnt_ns(tsk, tsk->fs);
1532 if (!new_ns) {
1533 err = -ENOMEM;
1534 goto out;
1535 }
1536 1530
1537 tsk->nsproxy->mnt_ns = new_ns;
1538
1539out:
1540 put_mnt_ns(ns); 1531 put_mnt_ns(ns);
1541 return err; 1532 return new_ns;
1542} 1533}
1543 1534
1544asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name, 1535asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name,