syscalls/ptrace07: handle potential SIGSEGV on older kernels
PATCH 1/1 syscalls/ptrace07: handle potential SIGSEGV on older kernels
If a ptraced test process hits SIGSEGV, the entire testcase hangs.
Older kernels such as RHEL7 (3.10.0), check the error code returned by restore_fpu_checking() and do drop_init_fpu() if it fails. So the FPU state of the prev task can't leak.
But in the more likely case a task with xcomp_bv != 0 will be killed by SIGSEGV; either from do_device_not_available() or from sys_rt_sigreturn()->__restore_xstate_sig().
And this is why the test case hangs; it wrongly assumes that the traced child can only exit and report nothing else. But since it receives SIGSEGV it reports this signal to the main process and sleeps in ptrace_stop(), it does not exit and thus the test-case hangs in tst_reap_children() after return from do_test().
Replace PTRACE_CONT with PTRACE_DETACH, so we don't need to handle subsequent stops. And treat exit code from test process as info-only.
--- testcases/kernel/syscalls/ptrace/ptrace07.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-)
testcases/kernel/syscalls/ptrace/ptrace07.c +23 -3
@@ -153,12 +153,32 @@ static void do_test(void) "PTRACE_SETREGSET failed with unexpected error"); } -TEST (ptrace (PTRACE_CONT , pid,0 ,0 )); +/* +* It is possible for test child 'pid' to crash on AMD +* systems (e.g. AMD Opteron(TM) Processor 6234) with +* older kernels. This causes tracee to stop and sleep +* in ptrace_stop(). Without resuming the tracee, the +* test hangs at do_test()->tst_reap_children() called +* by the library. Use detach here, so we don't need to +* worry about potential stops after this point. +*/ +TEST (ptrace (PTRACE_DETACH , pid,0 ,0 ));if (TST_RET !=0 ) -tst_brk (TBROK |TTERRNO ,"PTRACE_CONT failed" ); +tst_brk (TBROK |TTERRNO ,"PTRACE_DETACH failed" ); + +/* If child 'pid' crashes, only report it as info. */ +SAFE_WAITPID (pid, &status,0 ); +if (WIFEXITED (status)) { +tst_res (TINFO ,"test child %d exited, retcode: %d" , + pid,WEXITSTATUS (status)); + } +if (WIFSIGNALED (status)) { +tst_res (TINFO ,"test child %d exited, termsig: %d" , + pid,WTERMSIG (status)); + } okay = true; -for (i =0 ; i < num_cpus +1 ; i++) { +for (i =0 ; i < num_cpus; i++) {SAFE_WAIT (&status); okay &= (WIFEXITED (status) &&WEXITSTATUS (status) ==0 ); }
Signature · 1 line
1.8.3.1
PATCH 1/1 syscalls/ptrace07: handle potential SIGSEGV on older kernels
Quoted 28 lines · Jan Stancek
testcases/kernel/syscalls/ptrace/ptrace07.c +18
-2@@ -153,12 +153,32 @@ static void do_test(void) "PTRACE_SETREGSET failed with unexpected error"); } -TEST (ptrace (PTRACE_CONT , pid,0 ,0 )); +/* +* It is possible for test child 'pid' to crash on AMD +* systems (e.g. AMD Opteron(TM) Processor 6234) with +* older kernels. This causes tracee to stop and sleep +* in ptrace_stop(). Without resuming the tracee, the +* test hangs at do_test()->tst_reap_children() called +* by the library. Use detach here, so we don't need to +* worry about potential stops after this point. +*/ +TEST (ptrace (PTRACE_DETACH , pid,0 ,0 ));if (TST_RET !=0 ) -tst_brk (TBROK |TTERRNO ,"PTRACE_CONT failed" ); +tst_brk (TBROK |TTERRNO ,"PTRACE_DETACH failed" ); + +/* If child 'pid' crashes, only report it as info. */ +SAFE_WAITPID (pid, &status,0 ); +if (WIFEXITED (status)) { +tst_res (TINFO ,"test child %d exited, retcode: %d" , + pid,WEXITSTATUS (status)); + }
testcases/kernel/syscalls/ptrace/ptrace07.c static void do_test(void) · line 183
Quoted 10 lines
testcases/kernel/syscalls/ptrace/ptrace07.c +5
-1+if (WIFSIGNALED (status)) { +tst_res (TINFO ,"test child %d exited, termsig: %d" , + pid,WTERMSIG (status)); + } okay = true; -for (i =0 ; i < num_cpus +1 ; i++) { +for (i =0 ; i < num_cpus; i++) {SAFE_WAIT (&status); okay &= (WIFEXITED (status) &&WEXITSTATUS (status) ==0 );
Thanks Jan!
I think this change is correct.
Oleg.
PATCH 1/1 syscalls/ptrace07: handle potential SIGSEGV on older kernels
In reply to Jan StancekQuoted 17 lines · Jan Stancek
If a ptraced test process hits SIGSEGV, the entire testcase hangs.
Older kernels such as RHEL7 (3.10.0), check the error code returned by
restore_fpu_checking()and dodrop_init_fpu()if it fails. So the FPU state of the prev task can't leak.But in the more likely case a task with
xcomp_bv!= 0 will be killed by SIGSEGV; either fromdo_device_not_available()or from sys_rt_sigreturn()->__restore_xstate_sig().And this is why the test case hangs; it wrongly assumes that the traced child can only exit and report nothing else. But since it receives SIGSEGV it reports this signal to the main process and sleeps in
ptrace_stop(), it does not exit and thus the test-case hangs intst_reap_children()after return fromdo_test().
Quoted 3 lines
Replace
PTRACE_CONTwithPTRACE_DETACH, so we don't need to handle subsequent stops. And treat exit code from test process as info-only.
ptrace07(with this patch applied) passed with kernel 3.10 and 4.18 multi arches test.
Quoted 3 lines
Debugged-by Oleg Nesterov <[email protected]>Signed-off-by Jan Stancek <[email protected]>
Signature · 2 lines
Regards, Li Wang
PATCH 1/1 syscalls/ptrace07: handle potential SIGSEGV on older kernels
----- Original Message -----
Quoted 22 lines · Jan Stancek
Quoted 17 lines
If a ptraced test process hits SIGSEGV, the entire testcase hangs.
Older kernels such as RHEL7 (3.10.0), check the error code returned by
restore_fpu_checking()and dodrop_init_fpu()if it fails. So the FPU state of the prev task can't leak.But in the more likely case a task with
xcomp_bv!= 0 will be killed by SIGSEGV; either fromdo_device_not_available()or from sys_rt_sigreturn()->__restore_xstate_sig().And this is why the test case hangs; it wrongly assumes that the traced child can only exit and report nothing else. But since it receives SIGSEGV it reports this signal to the main process and sleeps in
ptrace_stop(), it does not exit and thus the test-case hangs intst_reap_children()after return fromdo_test().Quoted 3 lines
Replace
PTRACE_CONTwithPTRACE_DETACH, so we don't need to handle subsequent stops. And treat exit code from test process as info-only.
Quoted 8 lines
ptrace07(with this patch applied) passed with kernel 3.10 and 4.18 multi arches test.
Quoted 3 lines
Debugged-by Oleg Nesterov <[email protected]>Signed-off-by Jan Stancek <[email protected]>Tested-by Li Wang <[email protected]>
Pushed.
Regards,
Jan