aboutsummaryrefslogtreecommitdiffstats
path: root/fs/compat.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2009-03-30 07:20:30 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2009-03-31 23:00:26 -0400
commit498052bba55ecaff58db6a1436b0e25bfd75a7ff (patch)
treebd3644ac60737e3733995a203acebd70cfd1b21b /fs/compat.c
parent3e93cd671813e204c258f1e6c797959920cf7772 (diff)
New locking/refcounting for fs_struct
* all changes of current->fs are done under task_lock and write_lock of old fs->lock * refcount is not atomic anymore (same protection) * its decrements are done when removing reference from current; at the same time we decide whether to free it. * put_fs_struct() is gone * new field - ->in_exec. Set by check_unsafe_exec() if we are trying to do execve() and only subthreads share fs_struct. Cleared when finishing exec (success and failure alike). Makes CLONE_FS fail with -EAGAIN if set. * check_unsafe_exec() may fail with -EAGAIN if another execve() from subthread is in progress. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/compat.c')
-rw-r--r--fs/compat.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/fs/compat.c b/fs/compat.c
index 55efdfebdf5a..baabf203b847 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -51,6 +51,7 @@
51#include <linux/poll.h> 51#include <linux/poll.h>
52#include <linux/mm.h> 52#include <linux/mm.h>
53#include <linux/eventpoll.h> 53#include <linux/eventpoll.h>
54#include <linux/fs_struct.h>
54 55
55#include <asm/uaccess.h> 56#include <asm/uaccess.h>
56#include <asm/mmu_context.h> 57#include <asm/mmu_context.h>
@@ -1441,12 +1442,15 @@ int compat_do_execve(char * filename,
1441 bprm->cred = prepare_exec_creds(); 1442 bprm->cred = prepare_exec_creds();
1442 if (!bprm->cred) 1443 if (!bprm->cred)
1443 goto out_unlock; 1444 goto out_unlock;
1444 check_unsafe_exec(bprm); 1445
1446 retval = check_unsafe_exec(bprm);
1447 if (retval)
1448 goto out_unlock;
1445 1449
1446 file = open_exec(filename); 1450 file = open_exec(filename);
1447 retval = PTR_ERR(file); 1451 retval = PTR_ERR(file);
1448 if (IS_ERR(file)) 1452 if (IS_ERR(file))
1449 goto out_unlock; 1453 goto out_unmark;
1450 1454
1451 sched_exec(); 1455 sched_exec();
1452 1456
@@ -1488,6 +1492,9 @@ int compat_do_execve(char * filename,
1488 goto out; 1492 goto out;
1489 1493
1490 /* execve succeeded */ 1494 /* execve succeeded */
1495 write_lock(&current->fs->lock);
1496 current->fs->in_exec = 0;
1497 write_unlock(&current->fs->lock);
1491 current->in_execve = 0; 1498 current->in_execve = 0;
1492 mutex_unlock(&current->cred_exec_mutex); 1499 mutex_unlock(&current->cred_exec_mutex);
1493 acct_update_integrals(current); 1500 acct_update_integrals(current);
@@ -1506,6 +1513,11 @@ out_file:
1506 fput(bprm->file); 1513 fput(bprm->file);
1507 } 1514 }
1508 1515
1516out_unmark:
1517 write_lock(&current->fs->lock);
1518 current->fs->in_exec = 0;
1519 write_unlock(&current->fs->lock);
1520
1509out_unlock: 1521out_unlock:
1510 current->in_execve = 0; 1522 current->in_execve = 0;
1511 mutex_unlock(&current->cred_exec_mutex); 1523 mutex_unlock(&current->cred_exec_mutex);