Message ID | 1605233273-3784-1-git-send-email-xuyang2018.jy@cn.fujitsu.com |
---|---|
State | Changes Requested |
Headers | show |
Series | [v3] syscalls/ptrace11: Add test for tracing init process | expand |
Hi! > + /* > + * Running attach/detach more times will trigger a ESRCH error because > + * ptrace_check_attach function in kernel will report it if its process > + * stats is not __TASK_TRACED. > + */ > + TST_RETRY_FUNC(ptrace(PTRACE_DETACH, 1, NULL, NULL), TST_RETVAL_EQ0); Why do we have to retry the detach here? Other than that the rest looks fine now.
Hi Cyril > Hi! >> + /* >> + * Running attach/detach more times will trigger a ESRCH error because >> + * ptrace_check_attach function in kernel will report it if its process >> + * stats is not __TASK_TRACED. >> + */ >> + TST_RETRY_FUNC(ptrace(PTRACE_DETACH, 1, NULL, NULL), TST_RETVAL_EQ0); > > Why do we have to retry the detach here? I add a retry here because running attach/detach serval times may make init process isn't traced status . Even we have do attach action, detach will get ESRCH error . In kernel/ptrace.c code, it has the following calltrace SYSCALL_DEFINE4(ptrace... =>ptrace_check_attach //if we don't use PTRACE_ATTACH/PTRACE_SEIZE =>ptrace_freeze_traced /* Ensure that nothing can wake it up, even SIGKILL */ static bool ptrace_freeze_traced(struct task_struct *task) { bool ret = false; /* Lockless, nobody but us can set this flag */ if (task->jobctl & JOBCTL_LISTENING) return ret; spin_lock_irq(&task->sighand->siglock); if (task_is_traced(task) && !__fatal_signal_pending(task)) { task->state = __TASK_TRACED; ret = true; } spin_unlock_irq(&task->sighand->siglock); return ret; } ptrace_freeze_traced() may returns false when we run attach/detach serval times, so ptrace_check_attach returns ESRCH error . To be honset, I don't figure out why task->stat is not task_traced status after attaching. I am looking into this. Best Regards Yang Xu > > Other than that the rest looks fine now. >
Hi! > >> + /* > >> + * Running attach/detach more times will trigger a ESRCH error because > >> + * ptrace_check_attach function in kernel will report it if its process > >> + * stats is not __TASK_TRACED. > >> + */ > >> + TST_RETRY_FUNC(ptrace(PTRACE_DETACH, 1, NULL, NULL), TST_RETVAL_EQ0); > > > > Why do we have to retry the detach here? > > I add a retry here because running attach/detach serval times may make > init process isn't traced status . Even we have do attach action, detach > will get ESRCH error . Looking at the manual page it says: PTRACE_ATTACH ... The tracee is sent a SIGSTOP, but will not necessarily have stopped by the completion of this call; use waitpid(2) to wait for the tracee to stop. ... So my guess is that if we call PTRACE_ATTACH followed by the PTRACE_DETACH we may end up in a state where the SIGSTOP for the traced process haven't arrived yet and in this case we should get ESCRCH. So the correct solution is waitpid() for the traced process before we detach it.
Hi Cyril > Hi! >>>> + /* >>>> + * Running attach/detach more times will trigger a ESRCH error because >>>> + * ptrace_check_attach function in kernel will report it if its process >>>> + * stats is not __TASK_TRACED. >>>> + */ >>>> + TST_RETRY_FUNC(ptrace(PTRACE_DETACH, 1, NULL, NULL), TST_RETVAL_EQ0); >>> >>> Why do we have to retry the detach here? >> >> I add a retry here because running attach/detach serval times may make >> init process isn't traced status . Even we have do attach action, detach >> will get ESRCH error . > > Looking at the manual page it says: > > PTRACE_ATTACH > > ... > The tracee is sent a SIGSTOP, but will not necessarily have stopped by > the completion of this call; use waitpid(2) to wait for the tracee to > stop. Oh, I ignored it. Sorry. > ... > > So my guess is that if we call PTRACE_ATTACH followed by the > PTRACE_DETACH we may end up in a state where the SIGSTOP for the traced > process haven't arrived yet and in this case we should get ESCRCH. > > So the correct solution is waitpid() for the traced process before we > detach it. Yes, using waitpid() is ok. I Will send a v4 soon. >
diff --git a/runtest/syscalls b/runtest/syscalls index aeacb8bc8..6b5908662 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -1000,6 +1000,7 @@ ptrace07 ptrace07 ptrace08 ptrace08 ptrace09 ptrace09 ptrace10 ptrace10 +ptrace11 ptrace11 pwrite01 pwrite01 pwrite02 pwrite02 diff --git a/testcases/kernel/syscalls/ptrace/.gitignore b/testcases/kernel/syscalls/ptrace/.gitignore index 34be5148f..01cbc6072 100644 --- a/testcases/kernel/syscalls/ptrace/.gitignore +++ b/testcases/kernel/syscalls/ptrace/.gitignore @@ -7,3 +7,4 @@ /ptrace08 /ptrace09 /ptrace10 +/ptrace11 diff --git a/testcases/kernel/syscalls/ptrace/ptrace11.c b/testcases/kernel/syscalls/ptrace/ptrace11.c new file mode 100644 index 000000000..28a08f69d --- /dev/null +++ b/testcases/kernel/syscalls/ptrace/ptrace11.c @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved. + * Author: Yang Xu <xuyang2018.jy@cn.fujitsu.com> + * + * Before kernel 2.6.26, we can't trace init(1) process and ptrace() will + * get EPERM error. This case just check whether we can trace init(1) + * process and doesn't trigger error. + */ + +#include <errno.h> +#include <signal.h> +#include <sys/wait.h> +#include <pwd.h> +#include <config.h> +#include <stdlib.h> +#include "ptrace.h" +#include "tst_test.h" + +static void verify_ptrace(void) +{ + TEST(ptrace(PTRACE_ATTACH, 1, NULL, NULL)); + if (TST_RET == 0) + tst_res(TPASS, "ptrace() traces init process successfully"); + else + tst_res(TFAIL | TTERRNO, + "ptrace() returns %ld, failed unexpectedly", TST_RET); + + /* + * Running attach/detach more times will trigger a ESRCH error because + * ptrace_check_attach function in kernel will report it if its process + * stats is not __TASK_TRACED. + */ + TST_RETRY_FUNC(ptrace(PTRACE_DETACH, 1, NULL, NULL), TST_RETVAL_EQ0); +} + +static struct tst_test test = { + .test_all = verify_ptrace, + .needs_root = 1, +};
Before kernel 2.6.26, ptrace can't trace init process and will get EPERM error. Now, it should succeed when we have enough privileges. Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com> --- runtest/syscalls | 1 + testcases/kernel/syscalls/ptrace/.gitignore | 1 + testcases/kernel/syscalls/ptrace/ptrace11.c | 40 +++++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 testcases/kernel/syscalls/ptrace/ptrace11.c