aboutsummaryrefslogtreecommitdiffstats
path: root/fs/compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/compat.c')
-rw-r--r--fs/compat.c45
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 */
386asmlinkage 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
381static int get_compat_flock(struct flock *kfl, struct compat_flock __user *ufl) 409static 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(&current->cred_exec_mutex); 1435 retval = mutex_lock_interruptible(&current->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(&current->cred_exec_mutex); 1492 mutex_unlock(&current->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
1462out: 1499out:
@@ -1470,11 +1507,15 @@ out_file:
1470 } 1507 }
1471 1508
1472out_unlock: 1509out_unlock:
1510 current->in_execve = 0;
1473 mutex_unlock(&current->cred_exec_mutex); 1511 mutex_unlock(&current->cred_exec_mutex);
1474 1512
1475out_free: 1513out_free:
1476 free_bprm(bprm); 1514 free_bprm(bprm);
1477 1515
1516out_files:
1517 if (displaced)
1518 reset_files_struct(displaced);
1478out_ret: 1519out_ret:
1479 return retval; 1520 return retval;
1480} 1521}