diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/namespace.c | 56 |
1 files changed, 36 insertions, 20 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index ce97becff461..a2bef5c81033 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -1325,27 +1325,17 @@ dput_out: | |||
1325 | return retval; | 1325 | return retval; |
1326 | } | 1326 | } |
1327 | 1327 | ||
1328 | int 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 | */ | ||
1332 | struct 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); | 1396 | out: |
1409 | return 0; | 1397 | return new_ns; |
1398 | } | ||
1399 | |||
1400 | int 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 | ||
1411 | out: | 1427 | out: |
1412 | put_namespace(namespace); | 1428 | put_namespace(namespace); |
1413 | return -ENOMEM; | 1429 | return err; |
1414 | } | 1430 | } |
1415 | 1431 | ||
1416 | asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name, | 1432 | asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name, |