projects
/
cascardo
/
linux.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec...
[cascardo/linux.git]
/
fs
/
exec.c
diff --git
a/fs/exec.c
b/fs/exec.c
index
052a961
..
639177b
100644
(file)
--- a/
fs/exec.c
+++ b/
fs/exec.c
@@
-69,17
+69,18
@@
int suid_dumpable = 0;
static LIST_HEAD(formats);
static DEFINE_RWLOCK(binfmt_lock);
static LIST_HEAD(formats);
static DEFINE_RWLOCK(binfmt_lock);
-int
register_binfmt(struct linux_binfmt * fm
t)
+int
__register_binfmt(struct linux_binfmt * fmt, int inser
t)
{
if (!fmt)
return -EINVAL;
write_lock(&binfmt_lock);
{
if (!fmt)
return -EINVAL;
write_lock(&binfmt_lock);
- list_add(&fmt->lh, &formats);
+ insert ? list_add(&fmt->lh, &formats) :
+ list_add_tail(&fmt->lh, &formats);
write_unlock(&binfmt_lock);
return 0;
}
write_unlock(&binfmt_lock);
return 0;
}
-EXPORT_SYMBOL(register_binfmt);
+EXPORT_SYMBOL(
__
register_binfmt);
void unregister_binfmt(struct linux_binfmt * fmt)
{
void unregister_binfmt(struct linux_binfmt * fmt)
{
@@
-1060,7
+1061,6
@@
EXPORT_SYMBOL(install_exec_creds);
int check_unsafe_exec(struct linux_binprm *bprm)
{
struct task_struct *p = current, *t;
int check_unsafe_exec(struct linux_binprm *bprm)
{
struct task_struct *p = current, *t;
- unsigned long flags;
unsigned n_fs;
int res = 0;
unsigned n_fs;
int res = 0;
@@
-1068,21
+1068,22
@@
int check_unsafe_exec(struct linux_binprm *bprm)
n_fs = 1;
write_lock(&p->fs->lock);
n_fs = 1;
write_lock(&p->fs->lock);
-
lock_task_sighand(p, &flags
);
+
rcu_read_lock(
);
for (t = next_thread(p); t != p; t = next_thread(t)) {
if (t->fs == p->fs)
n_fs++;
}
for (t = next_thread(p); t != p; t = next_thread(t)) {
if (t->fs == p->fs)
n_fs++;
}
+ rcu_read_unlock();
if (p->fs->users > n_fs) {
bprm->unsafe |= LSM_UNSAFE_SHARE;
} else {
if (p->fs->users > n_fs) {
bprm->unsafe |= LSM_UNSAFE_SHARE;
} else {
- if (p->fs->in_exec)
- res = -EAGAIN;
- p->fs->in_exec = 1;
+ res = -EAGAIN;
+ if (!p->fs->in_exec) {
+ p->fs->in_exec = 1;
+ res = 1;
+ }
}
}
-
- unlock_task_sighand(p, &flags);
write_unlock(&p->fs->lock);
return res;
write_unlock(&p->fs->lock);
return res;
@@
-1284,6
+1285,7
@@
int do_execve(char * filename,
struct linux_binprm *bprm;
struct file *file;
struct files_struct *displaced;
struct linux_binprm *bprm;
struct file *file;
struct files_struct *displaced;
+ bool clear_in_exec;
int retval;
retval = unshare_files(&displaced);
int retval;
retval = unshare_files(&displaced);
@@
-1306,8
+1308,9
@@
int do_execve(char * filename,
goto out_unlock;
retval = check_unsafe_exec(bprm);
goto out_unlock;
retval = check_unsafe_exec(bprm);
- if (retval)
+ if (retval
< 0
)
goto out_unlock;
goto out_unlock;
+ clear_in_exec = retval;
file = open_exec(filename);
retval = PTR_ERR(file);
file = open_exec(filename);
retval = PTR_ERR(file);
@@
-1355,9
+1358,7
@@
int do_execve(char * filename,
goto out;
/* execve succeeded */
goto out;
/* execve succeeded */
- write_lock(¤t->fs->lock);
current->fs->in_exec = 0;
current->fs->in_exec = 0;
- write_unlock(¤t->fs->lock);
current->in_execve = 0;
mutex_unlock(¤t->cred_exec_mutex);
acct_update_integrals(current);
current->in_execve = 0;
mutex_unlock(¤t->cred_exec_mutex);
acct_update_integrals(current);
@@
-1377,9
+1378,8
@@
out_file:
}
out_unmark:
}
out_unmark:
- write_lock(¤t->fs->lock);
- current->fs->in_exec = 0;
- write_unlock(¤t->fs->lock);
+ if (clear_in_exec)
+ current->fs->in_exec = 0;
out_unlock:
current->in_execve = 0;
out_unlock:
current->in_execve = 0;