|
@@ -1077,9 +1077,11 @@ int check_unsafe_exec(struct linux_binprm *bprm)
|
|
|
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);
|
|
@@ -1284,6 +1286,7 @@ int do_execve(char * filename,
|
|
|
struct linux_binprm *bprm;
|
|
|
struct file *file;
|
|
|
struct files_struct *displaced;
|
|
|
+ bool clear_in_exec;
|
|
|
int retval;
|
|
|
|
|
|
retval = unshare_files(&displaced);
|
|
@@ -1306,8 +1309,9 @@ int do_execve(char * filename,
|
|
|
goto out_unlock;
|
|
|
|
|
|
retval = check_unsafe_exec(bprm);
|
|
|
- if (retval)
|
|
|
+ if (retval < 0)
|
|
|
goto out_unlock;
|
|
|
+ clear_in_exec = retval;
|
|
|
|
|
|
file = open_exec(filename);
|
|
|
retval = PTR_ERR(file);
|
|
@@ -1355,9 +1359,7 @@ int 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);
|
|
@@ -1377,9 +1379,8 @@ out_file:
|
|
|
}
|
|
|
|
|
|
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;
|