mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-23 07:01:23 +00:00
exec: do not sleep in TASK_TRACED under ->cred_guard_mutex
Tom Horsley reports that his debugger hangs when it tries to read /proc/pid_of_tracee/maps, this happens since "mm_for_maps: take ->cred_guard_mutex to fix the race with exec" 04b836cbf19e885f8366bccb2e4b0474346c02d commit in 2.6.31. But the root of the problem lies in the fact that do_execve() path calls tracehook_report_exec() which can stop if the tracer sets PT_TRACE_EXEC. The tracee must not sleep in TASK_TRACED holding this mutex. Even if we remove ->cred_guard_mutex from mm_for_maps() and proc_pid_attr_write(), another task doing PTRACE_ATTACH should not hang until it is killed or the tracee resumes. With this patch do_execve() does not use ->cred_guard_mutex directly and we do not hold it throughout, instead: - introduce prepare_bprm_creds() helper, it locks the mutex and calls prepare_exec_creds() to initialize bprm->cred. - install_exec_creds() drops the mutex after commit_creds(), and thus before tracehook_report_exec()->ptrace_stop(). or, if exec fails, free_bprm() drops this mutex when bprm->cred != NULL which indicates install_exec_creds() was not called. Reported-by: Tom Horsley <tom.horsley@att.net> Signed-off-by: Oleg Nesterov <oleg@redhat.com> Acked-by: David Howells <dhowells@redhat.com> Cc: Roland McGrath <roland@redhat.com> Cc: James Morris <jmorris@namei.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
dd5d241ea9
commit
a2a8474c3f
3 changed files with 43 additions and 38 deletions
17
fs/compat.c
17
fs/compat.c
|
@ -1485,20 +1485,15 @@ int compat_do_execve(char * filename,
|
|||
if (!bprm)
|
||||
goto out_files;
|
||||
|
||||
retval = -ERESTARTNOINTR;
|
||||
if (mutex_lock_interruptible(¤t->cred_guard_mutex))
|
||||
retval = prepare_bprm_creds(bprm);
|
||||
if (retval)
|
||||
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);
|
||||
if (retval < 0)
|
||||
goto out_unlock;
|
||||
goto out_free;
|
||||
clear_in_exec = retval;
|
||||
current->in_execve = 1;
|
||||
|
||||
file = open_exec(filename);
|
||||
retval = PTR_ERR(file);
|
||||
|
@ -1547,7 +1542,6 @@ int compat_do_execve(char * filename,
|
|||
/* execve succeeded */
|
||||
current->fs->in_exec = 0;
|
||||
current->in_execve = 0;
|
||||
mutex_unlock(¤t->cred_guard_mutex);
|
||||
acct_update_integrals(current);
|
||||
free_bprm(bprm);
|
||||
if (displaced)
|
||||
|
@ -1567,10 +1561,7 @@ out_file:
|
|||
out_unmark:
|
||||
if (clear_in_exec)
|
||||
current->fs->in_exec = 0;
|
||||
|
||||
out_unlock:
|
||||
current->in_execve = 0;
|
||||
mutex_unlock(¤t->cred_guard_mutex);
|
||||
|
||||
out_free:
|
||||
free_bprm(bprm);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue