aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namespace.c')
-rw-r--r--fs/namespace.c58
1 files changed, 37 insertions, 21 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index ce97becff461..058a44865beb 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -494,7 +494,7 @@ void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill)
494 p->mnt_namespace = NULL; 494 p->mnt_namespace = NULL;
495 list_del_init(&p->mnt_child); 495 list_del_init(&p->mnt_child);
496 if (p->mnt_parent != p) 496 if (p->mnt_parent != p)
497 mnt->mnt_mountpoint->d_mounted--; 497 p->mnt_mountpoint->d_mounted--;
498 change_mnt_propagation(p, MS_PRIVATE); 498 change_mnt_propagation(p, MS_PRIVATE);
499 } 499 }
500} 500}
@@ -1325,27 +1325,17 @@ dput_out:
1325 return retval; 1325 return retval;
1326} 1326}
1327 1327
1328int copy_namespace(int flags, struct task_struct *tsk) 1328/*
1329 * Allocate a new namespace structure and populate it with contents
1330 * copied from the namespace of the passed in task structure.
1331 */
1332struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs)
1329{ 1333{
1330 struct namespace *namespace = tsk->namespace; 1334 struct namespace *namespace = tsk->namespace;
1331 struct namespace *new_ns; 1335 struct namespace *new_ns;
1332 struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL; 1336 struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL;
1333 struct fs_struct *fs = tsk->fs;
1334 struct vfsmount *p, *q; 1337 struct vfsmount *p, *q;
1335 1338
1336 if (!namespace)
1337 return 0;
1338
1339 get_namespace(namespace);
1340
1341 if (!(flags & CLONE_NEWNS))
1342 return 0;
1343
1344 if (!capable(CAP_SYS_ADMIN)) {
1345 put_namespace(namespace);
1346 return -EPERM;
1347 }
1348
1349 new_ns = kmalloc(sizeof(struct namespace), GFP_KERNEL); 1339 new_ns = kmalloc(sizeof(struct namespace), GFP_KERNEL);
1350 if (!new_ns) 1340 if (!new_ns)
1351 goto out; 1341 goto out;
@@ -1396,8 +1386,6 @@ int copy_namespace(int flags, struct task_struct *tsk)
1396 } 1386 }
1397 up_write(&namespace_sem); 1387 up_write(&namespace_sem);
1398 1388
1399 tsk->namespace = new_ns;
1400
1401 if (rootmnt) 1389 if (rootmnt)
1402 mntput(rootmnt); 1390 mntput(rootmnt);
1403 if (pwdmnt) 1391 if (pwdmnt)
@@ -1405,12 +1393,40 @@ int copy_namespace(int flags, struct task_struct *tsk)
1405 if (altrootmnt) 1393 if (altrootmnt)
1406 mntput(altrootmnt); 1394 mntput(altrootmnt);
1407 1395
1408 put_namespace(namespace); 1396out:
1409 return 0; 1397 return new_ns;
1398}
1399
1400int copy_namespace(int flags, struct task_struct *tsk)
1401{
1402 struct namespace *namespace = tsk->namespace;
1403 struct namespace *new_ns;
1404 int err = 0;
1405
1406 if (!namespace)
1407 return 0;
1408
1409 get_namespace(namespace);
1410
1411 if (!(flags & CLONE_NEWNS))
1412 return 0;
1413
1414 if (!capable(CAP_SYS_ADMIN)) {
1415 err = -EPERM;
1416 goto out;
1417 }
1418
1419 new_ns = dup_namespace(tsk, tsk->fs);
1420 if (!new_ns) {
1421 err = -ENOMEM;
1422 goto out;
1423 }
1424
1425 tsk->namespace = new_ns;
1410 1426
1411out: 1427out:
1412 put_namespace(namespace); 1428 put_namespace(namespace);
1413 return -ENOMEM; 1429 return err;
1414} 1430}
1415 1431
1416asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name, 1432asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name,