kernel/ptrace.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 43d6179508d6..ebbc9876914b 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -31,6 +31,7 @@ #include #include #include +#include #include /* for syscall_get_* */ @@ -390,10 +391,24 @@ static int ptrace_attach(struct task_struct *task, long request, * Protect exec's credential calculations against our interference; * SUID, SGID and LSM creds get determined differently * under ptrace. + * + * Don't wait forever on the credential lock if the target is + * going through an execve. + * + * Whatever. We don't have "mutex_lock_interruptible_timeout()". + * But this would be a disgusting hack even with it. */ - retval = -ERESTARTNOINTR; - if (mutex_lock_interruptible(&task->signal->cred_guard_mutex)) - goto out; + for (;;) { + if (mutex_trylock(&task->signal->cred_guard_mutex)) + break; + retval = -ERESTARTNOINTR; + if (signal_pending(current)) + goto out; + retval = -EAGAIN; + if (task->in_execve) + goto out; + msleep_interruptible(100); + } task_lock(task); retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH_REALCREDS);