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>
This commit is contained in:
16
fs/compat.c
16
fs/compat.c
@@ -51,6 +51,7 @@
|
||||
#include <linux/poll.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/eventpoll.h>
|
||||
#include <linux/fs_struct.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/mmu_context.h>
|
||||
@@ -1441,12 +1442,15 @@ int compat_do_execve(char * filename,
|
||||
bprm->cred = prepare_exec_creds();
|
||||
if (!bprm->cred)
|
||||
goto out_unlock;
|
||||
check_unsafe_exec(bprm);
|
||||
|
||||
retval = check_unsafe_exec(bprm);
|
||||
if (retval)
|
||||
goto out_unlock;
|
||||
|
||||
file = open_exec(filename);
|
||||
retval = PTR_ERR(file);
|
||||
if (IS_ERR(file))
|
||||
goto out_unlock;
|
||||
goto out_unmark;
|
||||
|
||||
sched_exec();
|
||||
|
||||
@@ -1488,6 +1492,9 @@ int compat_do_execve(char * filename,
|
||||
goto out;
|
||||
|
||||
/* execve succeeded */
|
||||
write_lock(¤t->fs->lock);
|
||||
current->fs->in_exec = 0;
|
||||
write_unlock(¤t->fs->lock);
|
||||
current->in_execve = 0;
|
||||
mutex_unlock(¤t->cred_exec_mutex);
|
||||
acct_update_integrals(current);
|
||||
@@ -1506,6 +1513,11 @@ out_file:
|
||||
fput(bprm->file);
|
||||
}
|
||||
|
||||
out_unmark:
|
||||
write_lock(¤t->fs->lock);
|
||||
current->fs->in_exec = 0;
|
||||
write_unlock(¤t->fs->lock);
|
||||
|
||||
out_unlock:
|
||||
current->in_execve = 0;
|
||||
mutex_unlock(¤t->cred_exec_mutex);
|
||||
|
Reference in New Issue
Block a user