From: David Howells CRED: Take cred_exec_mutex in compat_do_execve() and fix error handling in do_execve() Take cred_exec_mutex in compat_do_execve(). This reflects what do_execve() does. The mutex protects credentials calculation against PTRACE_ATTACH needing to alter it mid-exec. Also fix the error handling in do_execve(). The mutex needs to be unlocked if an error occurs after it is taken, but before the install_exec_creds() released it. Signed-off-by: David Howells --- fs/compat.c | 12 ++++++++++-- fs/exec.c | 12 ++++++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/fs/compat.c b/fs/compat.c index 2dde882..af24b8a 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -1360,15 +1360,20 @@ int compat_do_execve(char * filename, if (!bprm) goto out_ret; + retval = mutex_lock_interruptible(¤t->cred_exec_mutex); + if (retval < 0) + goto out_free; + + retval = -ENOMEM; bprm->cred = prepare_exec_creds(); if (!bprm->cred) - goto out_free; + goto out_unlock; check_unsafe_exec(bprm); file = open_exec(filename); retval = PTR_ERR(file); if (IS_ERR(file)) - goto out_free; + goto out_unlock; sched_exec(); @@ -1423,6 +1428,9 @@ out_file: fput(bprm->file); } +out_unlock: + mutex_unlock(¤t->cred_exec_mutex); + out_free: free_bprm(bprm); diff --git a/fs/exec.c b/fs/exec.c index a7633e5..4b31a72 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1308,18 +1308,18 @@ int do_execve(char * filename, retval = mutex_lock_interruptible(¤t->cred_exec_mutex); if (retval < 0) - goto out_kfree; + goto out_free; retval = -ENOMEM; bprm->cred = prepare_exec_creds(); if (!bprm->cred) - goto out_kfree; + goto out_unlock; check_unsafe_exec(bprm); file = open_exec(filename); retval = PTR_ERR(file); if (IS_ERR(file)) - goto out_kfree; + goto out_unlock; sched_exec(); @@ -1376,7 +1376,11 @@ out_file: allow_write_access(bprm->file); fput(bprm->file); } -out_kfree: + +out_unlock: + mutex_unlock(¤t->cred_exec_mutex); + +out_free: free_bprm(bprm); out_files: