forked from luck/tmp_suning_uos_patched
ptrace: Reimplement PTRACE_KILL by always sending SIGKILL
commit 6a2d90ba027adba528509ffa27097cffd3879257 upstream. The current implementation of PTRACE_KILL is buggy and has been for many years as it assumes it's target has stopped in ptrace_stop. At a quick skim it looks like this assumption has existed since ptrace support was added in linux v1.0. While PTRACE_KILL has been deprecated we can not remove it as a quick search with google code search reveals many existing programs calling it. When the ptracee is not stopped at ptrace_stop some fields would be set that are ignored except in ptrace_stop. Making the userspace visible behavior of PTRACE_KILL a noop in those case. As the usual rules are not obeyed it is not clear what the consequences are of calling PTRACE_KILL on a running process. Presumably userspace does not do this as it achieves nothing. Replace the implementation of PTRACE_KILL with a simple send_sig_info(SIGKILL) followed by a return 0. This changes the observable user space behavior only in that PTRACE_KILL on a process not stopped in ptrace_stop will also kill it. As that has always been the intent of the code this seems like a reasonable change. Cc: stable@vger.kernel.org Reported-by: Al Viro <viro@zeniv.linux.org.uk> Suggested-by: Al Viro <viro@zeniv.linux.org.uk> Tested-by: Kees Cook <keescook@chromium.org> Reviewed-by: Oleg Nesterov <oleg@redhat.com> Link: https://lkml.kernel.org/r/20220505182645.497868-7-ebiederm@xmission.com Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
f8ef79687b
commit
b49516583f
|
@ -175,8 +175,7 @@ void set_task_blockstep(struct task_struct *task, bool on)
|
||||||
*
|
*
|
||||||
* NOTE: this means that set/clear TIF_BLOCKSTEP is only safe if
|
* NOTE: this means that set/clear TIF_BLOCKSTEP is only safe if
|
||||||
* task is current or it can't be running, otherwise we can race
|
* task is current or it can't be running, otherwise we can race
|
||||||
* with __switch_to_xtra(). We rely on ptrace_freeze_traced() but
|
* with __switch_to_xtra(). We rely on ptrace_freeze_traced().
|
||||||
* PTRACE_KILL is not safe.
|
|
||||||
*/
|
*/
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
debugctl = get_debugctlmsr();
|
debugctl = get_debugctlmsr();
|
||||||
|
|
|
@ -1219,9 +1219,8 @@ int ptrace_request(struct task_struct *child, long request,
|
||||||
return ptrace_resume(child, request, data);
|
return ptrace_resume(child, request, data);
|
||||||
|
|
||||||
case PTRACE_KILL:
|
case PTRACE_KILL:
|
||||||
if (child->exit_state) /* already dead */
|
send_sig_info(SIGKILL, SEND_SIG_NOINFO, child);
|
||||||
return 0;
|
return 0;
|
||||||
return ptrace_resume(child, request, SIGKILL);
|
|
||||||
|
|
||||||
#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
|
#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
|
||||||
case PTRACE_GETREGSET:
|
case PTRACE_GETREGSET:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user