|
@@ -1015,6 +1015,35 @@ out:
|
|
|
|
|
|
EXPORT_SYMBOL(flush_old_exec);
|
|
EXPORT_SYMBOL(flush_old_exec);
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * Prepare credentials and lock ->cred_guard_mutex.
|
|
|
|
+ * install_exec_creds() commits the new creds and drops the lock.
|
|
|
|
+ * Or, if exec fails before, free_bprm() should release ->cred and
|
|
|
|
+ * and unlock.
|
|
|
|
+ */
|
|
|
|
+int prepare_bprm_creds(struct linux_binprm *bprm)
|
|
|
|
+{
|
|
|
|
+ if (mutex_lock_interruptible(¤t->cred_guard_mutex))
|
|
|
|
+ return -ERESTARTNOINTR;
|
|
|
|
+
|
|
|
|
+ bprm->cred = prepare_exec_creds();
|
|
|
|
+ if (likely(bprm->cred))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ mutex_unlock(¤t->cred_guard_mutex);
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void free_bprm(struct linux_binprm *bprm)
|
|
|
|
+{
|
|
|
|
+ free_arg_pages(bprm);
|
|
|
|
+ if (bprm->cred) {
|
|
|
|
+ mutex_unlock(¤t->cred_guard_mutex);
|
|
|
|
+ abort_creds(bprm->cred);
|
|
|
|
+ }
|
|
|
|
+ kfree(bprm);
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* install the new credentials for this executable
|
|
* install the new credentials for this executable
|
|
*/
|
|
*/
|
|
@@ -1024,12 +1053,13 @@ void install_exec_creds(struct linux_binprm *bprm)
|
|
|
|
|
|
commit_creds(bprm->cred);
|
|
commit_creds(bprm->cred);
|
|
bprm->cred = NULL;
|
|
bprm->cred = NULL;
|
|
-
|
|
|
|
- /* cred_guard_mutex must be held at least to this point to prevent
|
|
|
|
|
|
+ /*
|
|
|
|
+ * cred_guard_mutex must be held at least to this point to prevent
|
|
* ptrace_attach() from altering our determination of the task's
|
|
* ptrace_attach() from altering our determination of the task's
|
|
- * credentials; any time after this it may be unlocked */
|
|
|
|
-
|
|
|
|
|
|
+ * credentials; any time after this it may be unlocked.
|
|
|
|
+ */
|
|
security_bprm_committed_creds(bprm);
|
|
security_bprm_committed_creds(bprm);
|
|
|
|
+ mutex_unlock(¤t->cred_guard_mutex);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(install_exec_creds);
|
|
EXPORT_SYMBOL(install_exec_creds);
|
|
|
|
|
|
@@ -1246,14 +1276,6 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
|
|
|
|
|
|
EXPORT_SYMBOL(search_binary_handler);
|
|
EXPORT_SYMBOL(search_binary_handler);
|
|
|
|
|
|
-void free_bprm(struct linux_binprm *bprm)
|
|
|
|
-{
|
|
|
|
- free_arg_pages(bprm);
|
|
|
|
- if (bprm->cred)
|
|
|
|
- abort_creds(bprm->cred);
|
|
|
|
- kfree(bprm);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
/*
|
|
/*
|
|
* sys_execve() executes a new program.
|
|
* sys_execve() executes a new program.
|
|
*/
|
|
*/
|
|
@@ -1277,20 +1299,15 @@ int do_execve(char * filename,
|
|
if (!bprm)
|
|
if (!bprm)
|
|
goto out_files;
|
|
goto out_files;
|
|
|
|
|
|
- retval = -ERESTARTNOINTR;
|
|
|
|
- if (mutex_lock_interruptible(¤t->cred_guard_mutex))
|
|
|
|
|
|
+ retval = prepare_bprm_creds(bprm);
|
|
|
|
+ if (retval)
|
|
goto out_free;
|
|
goto out_free;
|
|
- current->in_execve = 1;
|
|
|
|
-
|
|
|
|
- retval = -ENOMEM;
|
|
|
|
- bprm->cred = prepare_exec_creds();
|
|
|
|
- if (!bprm->cred)
|
|
|
|
- goto out_unlock;
|
|
|
|
|
|
|
|
retval = check_unsafe_exec(bprm);
|
|
retval = check_unsafe_exec(bprm);
|
|
if (retval < 0)
|
|
if (retval < 0)
|
|
- goto out_unlock;
|
|
|
|
|
|
+ goto out_free;
|
|
clear_in_exec = retval;
|
|
clear_in_exec = retval;
|
|
|
|
+ current->in_execve = 1;
|
|
|
|
|
|
file = open_exec(filename);
|
|
file = open_exec(filename);
|
|
retval = PTR_ERR(file);
|
|
retval = PTR_ERR(file);
|
|
@@ -1340,7 +1357,6 @@ int do_execve(char * filename,
|
|
/* execve succeeded */
|
|
/* execve succeeded */
|
|
current->fs->in_exec = 0;
|
|
current->fs->in_exec = 0;
|
|
current->in_execve = 0;
|
|
current->in_execve = 0;
|
|
- mutex_unlock(¤t->cred_guard_mutex);
|
|
|
|
acct_update_integrals(current);
|
|
acct_update_integrals(current);
|
|
free_bprm(bprm);
|
|
free_bprm(bprm);
|
|
if (displaced)
|
|
if (displaced)
|
|
@@ -1360,10 +1376,7 @@ out_file:
|
|
out_unmark:
|
|
out_unmark:
|
|
if (clear_in_exec)
|
|
if (clear_in_exec)
|
|
current->fs->in_exec = 0;
|
|
current->fs->in_exec = 0;
|
|
-
|
|
|
|
-out_unlock:
|
|
|
|
current->in_execve = 0;
|
|
current->in_execve = 0;
|
|
- mutex_unlock(¤t->cred_guard_mutex);
|
|
|
|
|
|
|
|
out_free:
|
|
out_free:
|
|
free_bprm(bprm);
|
|
free_bprm(bprm);
|