diff options
Diffstat (limited to 'fs/compat.c')
-rw-r--r-- | fs/compat.c | 45 |
1 files changed, 43 insertions, 2 deletions
diff --git a/fs/compat.c b/fs/compat.c index d0145ca27572..55efdfebdf5a 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -378,6 +378,34 @@ out: | |||
378 | return error; | 378 | return error; |
379 | } | 379 | } |
380 | 380 | ||
381 | /* | ||
382 | * This is a copy of sys_ustat, just dealing with a structure layout. | ||
383 | * Given how simple this syscall is that apporach is more maintainable | ||
384 | * than the various conversion hacks. | ||
385 | */ | ||
386 | asmlinkage long compat_sys_ustat(unsigned dev, struct compat_ustat __user *u) | ||
387 | { | ||
388 | struct super_block *sb; | ||
389 | struct compat_ustat tmp; | ||
390 | struct kstatfs sbuf; | ||
391 | int err; | ||
392 | |||
393 | sb = user_get_super(new_decode_dev(dev)); | ||
394 | if (!sb) | ||
395 | return -EINVAL; | ||
396 | err = vfs_statfs(sb->s_root, &sbuf); | ||
397 | drop_super(sb); | ||
398 | if (err) | ||
399 | return err; | ||
400 | |||
401 | memset(&tmp, 0, sizeof(struct compat_ustat)); | ||
402 | tmp.f_tfree = sbuf.f_bfree; | ||
403 | tmp.f_tinode = sbuf.f_ffree; | ||
404 | if (copy_to_user(u, &tmp, sizeof(struct compat_ustat))) | ||
405 | return -EFAULT; | ||
406 | return 0; | ||
407 | } | ||
408 | |||
381 | static int get_compat_flock(struct flock *kfl, struct compat_flock __user *ufl) | 409 | static int get_compat_flock(struct flock *kfl, struct compat_flock __user *ufl) |
382 | { | 410 | { |
383 | if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)) || | 411 | if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)) || |
@@ -1392,22 +1420,28 @@ int compat_do_execve(char * filename, | |||
1392 | { | 1420 | { |
1393 | struct linux_binprm *bprm; | 1421 | struct linux_binprm *bprm; |
1394 | struct file *file; | 1422 | struct file *file; |
1423 | struct files_struct *displaced; | ||
1395 | int retval; | 1424 | int retval; |
1396 | 1425 | ||
1426 | retval = unshare_files(&displaced); | ||
1427 | if (retval) | ||
1428 | goto out_ret; | ||
1429 | |||
1397 | retval = -ENOMEM; | 1430 | retval = -ENOMEM; |
1398 | bprm = kzalloc(sizeof(*bprm), GFP_KERNEL); | 1431 | bprm = kzalloc(sizeof(*bprm), GFP_KERNEL); |
1399 | if (!bprm) | 1432 | if (!bprm) |
1400 | goto out_ret; | 1433 | goto out_files; |
1401 | 1434 | ||
1402 | retval = mutex_lock_interruptible(¤t->cred_exec_mutex); | 1435 | retval = mutex_lock_interruptible(¤t->cred_exec_mutex); |
1403 | if (retval < 0) | 1436 | if (retval < 0) |
1404 | goto out_free; | 1437 | goto out_free; |
1438 | current->in_execve = 1; | ||
1405 | 1439 | ||
1406 | retval = -ENOMEM; | 1440 | retval = -ENOMEM; |
1407 | bprm->cred = prepare_exec_creds(); | 1441 | bprm->cred = prepare_exec_creds(); |
1408 | if (!bprm->cred) | 1442 | if (!bprm->cred) |
1409 | goto out_unlock; | 1443 | goto out_unlock; |
1410 | check_unsafe_exec(bprm, current->files); | 1444 | check_unsafe_exec(bprm); |
1411 | 1445 | ||
1412 | file = open_exec(filename); | 1446 | file = open_exec(filename); |
1413 | retval = PTR_ERR(file); | 1447 | retval = PTR_ERR(file); |
@@ -1454,9 +1488,12 @@ int compat_do_execve(char * filename, | |||
1454 | goto out; | 1488 | goto out; |
1455 | 1489 | ||
1456 | /* execve succeeded */ | 1490 | /* execve succeeded */ |
1491 | current->in_execve = 0; | ||
1457 | mutex_unlock(¤t->cred_exec_mutex); | 1492 | mutex_unlock(¤t->cred_exec_mutex); |
1458 | acct_update_integrals(current); | 1493 | acct_update_integrals(current); |
1459 | free_bprm(bprm); | 1494 | free_bprm(bprm); |
1495 | if (displaced) | ||
1496 | put_files_struct(displaced); | ||
1460 | return retval; | 1497 | return retval; |
1461 | 1498 | ||
1462 | out: | 1499 | out: |
@@ -1470,11 +1507,15 @@ out_file: | |||
1470 | } | 1507 | } |
1471 | 1508 | ||
1472 | out_unlock: | 1509 | out_unlock: |
1510 | current->in_execve = 0; | ||
1473 | mutex_unlock(¤t->cred_exec_mutex); | 1511 | mutex_unlock(¤t->cred_exec_mutex); |
1474 | 1512 | ||
1475 | out_free: | 1513 | out_free: |
1476 | free_bprm(bprm); | 1514 | free_bprm(bprm); |
1477 | 1515 | ||
1516 | out_files: | ||
1517 | if (displaced) | ||
1518 | reset_files_struct(displaced); | ||
1478 | out_ret: | 1519 | out_ret: |
1479 | return retval; | 1520 | return retval; |
1480 | } | 1521 | } |