powerpc/ptrace: replace ptrace_report_syscall() with a tracehook call
Subsystems (2)
PATCH v2 1/1 powerpc/ptrace: replace ptrace_report_syscall() with a tracehook call
Arch code should use tracehook_*() helpers, as documented in include/linux/tracehook.h.
--- arch/powerpc/kernel/ptrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/kernel/ptrace.c +1 -1
@@ -3266,7 +3266,7 @@ long do_syscall_trace_enter(struct pt_regs *regs)user_exit ();if (test_thread_flag (TIF_SYSCALL_EMU )) { -ptrace_report_syscall (regs); + (void )tracehook_report_syscall_entry (regs);/* * Returning -1 will skip the syscall execution. We want to * avoid clobbering any register also, thus, not 'gotoing'
Signature · 1 line
2.19.1
Michael Ellerman
reviewerQuoted 2 lines · Elvira Khabirova
Arch code should use tracehook_*() helpers, as documented in
include/linux/tracehook.h.
Thanks.
It probably also should have a comment explaining why we're ignoring the return value and why that's OK.
cheers
Quoted 21 lines
Fixes 5521eb4bca2d ("powerpc/ptrace: Add support for PTRACE_SYSEMU")Signed-off-by Elvira Khabirova <[email protected]>--- arch/powerpc/kernel/ptrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)arch/powerpc/kernel/ptrace.c +1
-1@@ -3266,7 +3266,7 @@ long do_syscall_trace_enter(struct pt_regs *regs)user_exit ();if (test_thread_flag (TIF_SYSCALL_EMU )) { -ptrace_report_syscall (regs); + (void )tracehook_report_syscall_entry (regs);/* * Returning -1 will skip the syscall execution. We want to * avoid clobbering any register also, thus, not 'gotoing' Signature · 1 line
2.19.1
PATCH v3 1/1 powerpc/ptrace: replace ptrace_report_syscall() with a tracehook call
From: Elvira Khabirova <[email protected]>
Arch code should use tracehook_*() helpers as documented in include/linux/tracehook.h,ptrace_report_syscall() is not expected to be used outside that file.
---
v3: add a descriptive comment
v2: explicitly ignore tracehook_report_syscall_entry() return code
arch/powerpc/kernel/ptrace.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
arch/powerpc/kernel/ptrace.c +6 -1
@@ -3266,7 +3266,12 @@ long do_syscall_trace_enter(struct pt_regs *regs)user_exit ();if (test_thread_flag (TIF_SYSCALL_EMU )) { -ptrace_report_syscall (regs); +/* +* A nonzero return code from tracehook_report_syscall_entry() +* tells us to prevent the syscall execution, but we are not +* going to execute it anyway. +*/ + (void )tracehook_report_syscall_entry (regs);/* * Returning -1 will skip the syscall execution. We want to * avoid clobbering any register also, thus, not 'gotoing'
Signature · 1 line
ldv
Michael Ellerman
reviewerHi Dmitry,
Thanks for the patch.
Quoted 23 lines · Dmitry V. Levin
From: Elvira Khabirova <[email protected]>
Arch code should use tracehook_*() helpers as documented in
include/linux/tracehook.h,ptrace_report_syscall()is not expected to be used outside that file.Co-authored-by Dmitry V. Levin <[email protected]>Fixes 5521eb4bca2d ("powerpc/ptrace: Add support for PTRACE_SYSEMU")Signed-off-by Elvira Khabirova <[email protected]>Signed-off-by Dmitry V. Levin <[email protected]>---
v3: add a descriptive comment
v2: explicitly ignoretracehook_report_syscall_entry()return codearch/powerpc/kernel/ptrace.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)arch/powerpc/kernel/ptrace.c +0
-0
arch/powerpc/kernel/ptrace.c long do_syscall_trace_enter(struct pt_regs *regs) · line 3274
Quoted 10 lines
arch/powerpc/kernel/ptrace.c +6
-1@@ -3266,7 +3266,12 @@ long do_syscall_trace_enter(struct pt_regs *regs)user_exit ();if (test_thread_flag (TIF_SYSCALL_EMU )) { -ptrace_report_syscall (regs); +/* +* A nonzero return code from tracehook_report_syscall_entry() +* tells us to prevent the syscall execution, but we are not +* going to execute it anyway. +*/ + (void )tracehook_report_syscall_entry (regs);
Unfortunately the (void) cast doesn't work to suppress the must check warning.
arch/powerpc/kernel/ptrace.c:3274:3: error: ignoring return value of 'tracehook_report_syscall_entry', declared with attribute warn_unused_result [-Werror=unused-result]
AFAIK we don't have a way to suppress that.
I guess we should rewrite it to only call tracehook_report_syscall_entry() once, like x86 does.
I'll try and get a patch for that done & tested.
cheers
PATCH v4 1/1 powerpc/ptrace: replace ptrace_report_syscall() with a tracehook call
From: Elvira Khabirova <[email protected]>
Arch code should use tracehook_*() helpers, as documented in include/linux/tracehook.h,ptrace_report_syscall() is not expected to be used outside that file.
---
v4: rewritten to call tracehook_report_syscall_entry() once, compile-tested
v3: add a descriptive comment
v2: explicitly ignore tracehook_report_syscall_entry() return code
arch/powerpc/kernel/ptrace.c | 54 +++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 19 deletions(-)
arch/powerpc/kernel/ptrace.c +35 -19
@@ -3263,27 +3263,43 @@ static inline int do_seccomp(struct pt_regs *regs) { return 0; }*/ long do_syscall_trace_enter (struct pt_regs *regs) { +struct thread_info *ti; +u32 cached_flags; +user_exit (); -if (test_thread_flag (TIF_SYSCALL_EMU )) { -ptrace_report_syscall (regs); -/* -* Returning -1 will skip the syscall execution. We want to -* avoid clobbering any register also, thus, not 'gotoing' -* skip label. -*/ -return -1 ; - } + ti =current_thread_info (); + cached_flags = +READ_ONCE (ti->flags) & + (TIF_SYSCALL_EMU |TIF_SYSCALL_TRACE |TIF_SYSCALL_TRACEPOINT ); -/* -* The tracer may decide to abort the syscall, if so tracehook -* will return !0. Note that the tracer may also just change -* regs->gpr[0] to an invalid syscall number, that is handled -* below on the exit path. -*/ -if (test_thread_flag (TIF_SYSCALL_TRACE ) && -tracehook_report_syscall_entry (regs)) - goto skip; +if (cached_flags & (TIF_SYSCALL_EMU |TIF_SYSCALL_TRACE )) { +int rc =tracehook_report_syscall_entry (regs); + +if (unlikely (cached_flags & _TIF_SYSCALL_EMU)) { +/* +* A nonzero return code from +* tracehook_report_syscall_entry() tells us +* to prevent the syscall execution, but +* we are not going to execute it anyway. +* +* Returning -1 will skip the syscall execution. +* We want to avoid clobbering any register also, +* thus, not 'gotoing' skip label. +*/ +return -1 ; + } + +if (rc) { +/* +* The tracer decided to abort the syscall. +* Note that the tracer may also just change +* regs->gpr[0] to an invalid syscall number, +* that is handled below on the exit path. +*/ + goto skip; + } + }/* Run seccomp after ptrace; allow it to set gpr[3]. */ if (do_seccomp (regs))
@@ -3293,7 +3309,7 @@ long do_syscall_trace_enter(struct pt_regs *regs)if (regs->gpr[0 ] >= NR_syscalls) goto skip; -if (unlikely (test_thread_flag (TIF_SYSCALL_TRACEPOINT ))) +if (unlikely (cached_flags &TIF_SYSCALL_TRACEPOINT ))trace_sys_enter (regs, regs->gpr[0 ]);#ifdef CONFIG_PPC64
Signature · 1 line
ldv
Quoted 10 lines · Dmitry V. Levin
From: Elvira Khabirova <[email protected]>
Arch code should use tracehook_*() helpers, as documented in
include/linux/tracehook.h,ptrace_report_syscall()is not expected to be used outside that file.Co-authored-by Dmitry V. Levin <[email protected]>Fixes 5521eb4bca2d ("powerpc/ptrace: Add support for PTRACE_SYSEMU")Signed-off-by Elvira Khabirova <[email protected]>Signed-off-by Dmitry V. Levin <[email protected]>
Quoted 7 lines
---
v4: rewritten to calltracehook_report_syscall_entry()once, compile-tested
v3: add a descriptive comment
v2: explicitly ignoretracehook_report_syscall_entry()return codearch/powerpc/kernel/ptrace.c | 54 +++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 19 deletions(-)
Sorry, this patch does not work, please ignore it. However, the bug blocks PTRACE_GET_SYSCALL_INFO, so please fix it.
I'm going to use
if (tracehook_report_syscall_entry(regs)) return -1; return -1;
in the series until you have a better fix.
Signature · 1 line
ldv
Michael Ellerman
reviewerQuoted 16 lines · Dmitry V. Levin
Quoted 15 lines · Dmitry V. Levin
From: Elvira Khabirova <[email protected]>
Arch code should use tracehook_*() helpers, as documented in
include/linux/tracehook.h,ptrace_report_syscall()is not expected to be used outside that file.Co-authored-by Dmitry V. Levin <[email protected]>Fixes 5521eb4bca2d ("powerpc/ptrace: Add support for PTRACE_SYSEMU")Signed-off-by Elvira Khabirova <[email protected]>Signed-off-by Dmitry V. Levin <[email protected]>---
v4: rewritten to calltracehook_report_syscall_entry()once, compile-tested
v3: add a descriptive comment
v2: explicitly ignoretracehook_report_syscall_entry()return code
Quoted 4 lines
Quoted 2 lines
arch/powerpc/kernel/ptrace.c | 54 +++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 19 deletions(-)Sorry, this patch does not work, please ignore it.
Hmm OK. Why exactly?
I wrote more or less the same patch, although I used a temporary bool.
Quoted 1 line
However, the bug blocks
PTRACE_GET_SYSCALL_INFO, so please fix it.
Sorry, didn't realise it was blocking you.
Quoted 5 lines
I'm going to use
if (tracehook_report_syscall_entry(regs)) return -1; return -1;in the series until you have a better fix.
Yeah that's fine by me. I could send that to Linus for 4.20 if you want me to, otherwise I'm fine for you to carry it in your series.
cheers
Quoted 17 lines · Michael Ellerman
Quoted 16 lines · Dmitry V. Levin
Quoted 15 lines · Dmitry V. Levin
From: Elvira Khabirova <[email protected]>
Arch code should use tracehook_*() helpers, as documented in
include/linux/tracehook.h,ptrace_report_syscall()is not expected to be used outside that file.Co-authored-by Dmitry V. Levin <[email protected]>Fixes 5521eb4bca2d ("powerpc/ptrace: Add support for PTRACE_SYSEMU")Signed-off-by Elvira Khabirova <[email protected]>Signed-off-by Dmitry V. Levin <[email protected]>---
v4: rewritten to calltracehook_report_syscall_entry()once, compile-tested
v3: add a descriptive comment
v2: explicitly ignoretracehook_report_syscall_entry()return code
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines
arch/powerpc/kernel/ptrace.c | 54 +++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 19 deletions(-)Sorry, this patch does not work, please ignore it.
Hmm OK. Why exactly?
Unfortunately, I have no idea why it doesn't work.
All I can say is it breaks strace because the kernel no longer sends syscall entry stops.
Quoted 5 lines
I wrote more or less the same patch, although I used a temporary bool.
Quoted 1 line
However, the bug blocks
PTRACE_GET_SYSCALL_INFO, so please fix it.Sorry, didn't realise it was blocking you.
We are changing ptrace_report_syscall signature to implement PTRACE_GET_SYSCALL_INFO, and this is the only place in the kernel besides tracehook_report_syscall_*() that invokes ptrace_report_syscall() directly.
Quoted 8 lines
Quoted 5 lines
I'm going to use
if (tracehook_report_syscall_entry(regs)) return -1; return -1;in the series until you have a better fix.
Yeah that's fine by me. I could send that to Linus for 4.20 if you want me to, otherwise I'm fine for you to carry it in your series.
Yes, please. I'll send a v5 shortly.
Signature · 1 line
ldv
PATCH v5 1/1 powerpc/ptrace: replace ptrace_report_syscall() with a tracehook call
From: Elvira Khabirova <[email protected]>
Arch code should use tracehook_*() helpers, as documented in include/linux/tracehook.h,ptrace_report_syscall() is not expected to be used outside that file.
The patch does not look very nice, but at least it is correct and opens the way for PTRACE_GET_SYSCALL_INFO API.
---
v5: reverted to a simple approach, compile- and run-tested
v4: rewritten to call tracehook_report_syscall_entry() once, compile-tested
v3: add a descriptive comment
v2: explicitly ignore tracehook_report_syscall_entry() return code
arch/powerpc/kernel/ptrace.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
arch/powerpc/kernel/ptrace.c +6 -1
@@ -3266,12 +3266,17 @@ long do_syscall_trace_enter(struct pt_regs *regs)user_exit ();if (test_thread_flag (TIF_SYSCALL_EMU )) { -ptrace_report_syscall (regs);/* +* A nonzero return code from tracehook_report_syscall_entry() +* tells us to prevent the syscall execution, but we are not +* going to execute it anyway. +* * Returning -1 will skip the syscall execution. We want to * avoid clobbering any register also, thus, not 'gotoing' * skip label. */ +if (tracehook_report_syscall_entry (regs)) + ;return -1 ; }
Signature · 1 line
ldv
PATCH v6 1/1 powerpc/ptrace: replace ptrace_report_syscall() with a tracehook call
From: Elvira Khabirova <[email protected]>
Arch code should use tracehook_*() helpers, as documented in include/linux/tracehook.h,ptrace_report_syscall() is not expected to be used outside that file.
---
Please make either v5 or v6 edition of this fix, or any similar fix, into v4.20.
v6: reverted to a fixed version of v4, compile- and run-tested with strace
v5: reverted to a simple approach, compile- and run-tested
v4: rewritten to call tracehook_report_syscall_entry() once, compile-tested
v3: add a descriptive comment
v2: explicitly ignore tracehook_report_syscall_entry() return code
arch/powerpc/kernel/ptrace.c | 54 +++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 19 deletions(-)
arch/powerpc/kernel/ptrace.c +35 -19
@@ -3263,27 +3263,43 @@ static inline int do_seccomp(struct pt_regs *regs) { return 0; }*/ long do_syscall_trace_enter (struct pt_regs *regs) { +struct thread_info *ti; +u32 cached_flags; +user_exit (); -if (test_thread_flag (TIF_SYSCALL_EMU )) { -ptrace_report_syscall (regs); -/* -* Returning -1 will skip the syscall execution. We want to -* avoid clobbering any register also, thus, not 'gotoing' -* skip label. -*/ -return -1 ; - } + ti =current_thread_info (); + cached_flags =READ_ONCE (ti->flags) & + (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE | + _TIF_SYSCALL_TRACEPOINT); -/* -* The tracer may decide to abort the syscall, if so tracehook -* will return !0. Note that the tracer may also just change -* regs->gpr[0] to an invalid syscall number, that is handled -* below on the exit path. -*/ -if (test_thread_flag (TIF_SYSCALL_TRACE ) && -tracehook_report_syscall_entry (regs)) - goto skip; +if (cached_flags & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE)) { +int rc =tracehook_report_syscall_entry (regs); + +if (unlikely (cached_flags & _TIF_SYSCALL_EMU)) { +/* +* A nonzero return code from +* tracehook_report_syscall_entry() tells us +* to prevent the syscall execution, but +* we are not going to execute it anyway. +* +* Returning -1 will skip the syscall execution. +* We want to avoid clobbering any register also, +* thus, not 'gotoing' skip label. +*/ +return -1 ; + } + +if (rc) { +/* +* The tracer decided to abort the syscall. +* Note that the tracer may also just change +* regs->gpr[0] to an invalid syscall number, +* that is handled below on the exit path. +*/ + goto skip; + } + }/* Run seccomp after ptrace; allow it to set gpr[3]. */ if (do_seccomp (regs))
@@ -3293,7 +3309,7 @@ long do_syscall_trace_enter(struct pt_regs *regs)if (regs->gpr[0 ] >= NR_syscalls) goto skip; -if (unlikely (test_thread_flag (TIF_SYSCALL_TRACEPOINT ))) +if (unlikely (cached_flags & _TIF_SYSCALL_TRACEPOINT))trace_sys_enter (regs, regs->gpr[0 ]);#ifdef CONFIG_PPC64
Signature · 1 line
ldv
Oleg Nesterov
maintainerQuoted 3 lines · Dmitry V. Levin
Please make either v5 or v6 edition of this fix, or any similar fix, into v4.20.
IIUC, v5 above means
[PATCH v5 23/25] powerpc/ptrace: replace ptrace_report_syscall() with a tracehook call
you sent in another series...
Quoted 61 lines
long
do_syscall_trace_enter(struct pt_regs *regs){arch/powerpc/kernel/ptrace.c +34
-18+struct thread_info *ti; +u32 cached_flags; +user_exit (); -if (test_thread_flag (TIF_SYSCALL_EMU )) { -ptrace_report_syscall (regs); -/* -* Returning -1 will skip the syscall execution. We want to -* avoid clobbering any register also, thus, not 'gotoing' -* skip label. -*/ -return -1 ; - } + ti =current_thread_info (); + cached_flags =READ_ONCE (ti->flags) & + (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE | + _TIF_SYSCALL_TRACEPOINT); -/* -* The tracer may decide to abort the syscall, if so tracehook -* will return !0. Note that the tracer may also just change -* regs->gpr[0] to an invalid syscall number, that is handled -* below on the exit path. -*/ -if (test_thread_flag (TIF_SYSCALL_TRACE ) && -tracehook_report_syscall_entry (regs)) - goto skip; +if (cached_flags & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE)) { +int rc =tracehook_report_syscall_entry (regs); + +if (unlikely (cached_flags & _TIF_SYSCALL_EMU)) { +/* +* A nonzero return code from +* tracehook_report_syscall_entry() tells us +* to prevent the syscall execution, but +* we are not going to execute it anyway. +* +* Returning -1 will skip the syscall execution. +* We want to avoid clobbering any register also, +* thus, not 'gotoing' skip label. +*/ +return -1 ; + } + +if (rc) { +/* +* The tracer decided to abort the syscall. +* Note that the tracer may also just change +* regs->gpr[0] to an invalid syscall number, +* that is handled below on the exit path. +*/ + goto skip; + } + }/* Run seccomp after ptrace; allow it to set gpr[3]. */ if (do_seccomp (regs))
arch/powerpc/kernel/ptrace.c long do_syscall_trace_enter(struct pt_regs *regs) · line 3312
Quoted 5 lines
arch/powerpc/kernel/ptrace.c +1
-1@@ -3293,7 +3309,7 @@ long do_syscall_trace_enter(struct pt_regs *regs)if (regs->gpr[0 ] >= NR_syscalls) goto skip; -if (unlikely (test_thread_flag (TIF_SYSCALL_TRACEPOINT ))) +if (unlikely (cached_flags & _TIF_SYSCALL_TRACEPOINT))
I will leave this to maintainers, but to me this change looks good and imo it also cleanups the code.
However I am not sure cached_flags should include _TIF_SYSCALL_TRACEPOINT. If nothing else, the caller can sleep in ptrace_stop() unpredictably long and TIF_SYSCALL_TRACEPOINT can be set/cleared meanwhile.
Oleg.
Quoted 10 lines · Oleg Nesterov
Quoted 3 lines · Dmitry V. Levin
Please make either v5 or v6 edition of this fix, or any similar fix, into v4.20.
IIUC, v5 above means
[PATCH v5 23/25] powerpc/ptrace: replace
ptrace_report_syscall()with a tracehook callyou sent in another series...
They just happen to have the same v5 here and there.
In that series I included the most trivial variant of the change.
Quoted 70 lines
Quoted 61 lines
long
do_syscall_trace_enter(struct pt_regs *regs){arch/powerpc/kernel/ptrace.c +34
-18+struct thread_info *ti; +u32 cached_flags; +user_exit (); -if (test_thread_flag (TIF_SYSCALL_EMU )) { -ptrace_report_syscall (regs); -/* -* Returning -1 will skip the syscall execution. We want to -* avoid clobbering any register also, thus, not 'gotoing' -* skip label. -*/ -return -1 ; - } + ti =current_thread_info (); + cached_flags =READ_ONCE (ti->flags) & + (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE | + _TIF_SYSCALL_TRACEPOINT); -/* -* The tracer may decide to abort the syscall, if so tracehook -* will return !0. Note that the tracer may also just change -* regs->gpr[0] to an invalid syscall number, that is handled -* below on the exit path. -*/ -if (test_thread_flag (TIF_SYSCALL_TRACE ) && -tracehook_report_syscall_entry (regs)) - goto skip; +if (cached_flags & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE)) { +int rc =tracehook_report_syscall_entry (regs); + +if (unlikely (cached_flags & _TIF_SYSCALL_EMU)) { +/* +* A nonzero return code from +* tracehook_report_syscall_entry() tells us +* to prevent the syscall execution, but +* we are not going to execute it anyway. +* +* Returning -1 will skip the syscall execution. +* We want to avoid clobbering any register also, +* thus, not 'gotoing' skip label. +*/ +return -1 ; + } + +if (rc) { +/* +* The tracer decided to abort the syscall. +* Note that the tracer may also just change +* regs->gpr[0] to an invalid syscall number, +* that is handled below on the exit path. +*/ + goto skip; + } + }/* Run seccomp after ptrace; allow it to set gpr[3]. */ if (do_seccomp (regs))arch/powerpc/kernel/ptrace.c long do_syscall_trace_enter(struct pt_regs *regs) · line 3312
Quoted 5 lines
arch/powerpc/kernel/ptrace.c +1
-1@@ -3293,7 +3309,7 @@ long do_syscall_trace_enter(struct pt_regs *regs)if (regs->gpr[0 ] >= NR_syscalls) goto skip; -if (unlikely (test_thread_flag (TIF_SYSCALL_TRACEPOINT ))) +if (unlikely (cached_flags & _TIF_SYSCALL_TRACEPOINT))I will leave this to maintainers, but to me this change looks good and imo it also cleanups the code.
Quoted 3 lines
However I am not sure
cached_flagsshould include_TIF_SYSCALL_TRACEPOINT. If nothing else, the caller can sleep inptrace_stop()unpredictably long andTIF_SYSCALL_TRACEPOINTcan be set/cleared meanwhile.
I agree, we shouldn't cache _TIF_SYSCALL_TRACEPOINT.
Signature · 1 line
ldv
PATCH 1/1 powerpc/ptrace: cleanup do_syscall_trace_enter
Invoke tracehook_report_syscall_entry once.
--- arch/powerpc/kernel/ptrace.c | 54 +++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 23 deletions(-)
arch/powerpc/kernel/ptrace.c +31 -23
@@ -3263,32 +3263,40 @@ static inline int do_seccomp(struct pt_regs *regs) { return 0; }*/ long do_syscall_trace_enter (struct pt_regs *regs) { +u32 cached_flags; +user_exit (); -if (test_thread_flag (TIF_SYSCALL_EMU )) { -/* -* A nonzero return code from tracehook_report_syscall_entry() -* tells us to prevent the syscall execution, but we are not -* going to execute it anyway. -* -* Returning -1 will skip the syscall execution. We want to -* avoid clobbering any register also, thus, not 'gotoing' -* skip label. -*/ -if (tracehook_report_syscall_entry (regs)) - ; -return -1 ; - } + cached_flags =READ_ONCE (current_thread_info ()->flags) & + (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE); -/* -* The tracer may decide to abort the syscall, if so tracehook -* will return !0. Note that the tracer may also just change -* regs->gpr[0] to an invalid syscall number, that is handled -* below on the exit path. -*/ -if (test_thread_flag (TIF_SYSCALL_TRACE ) && -tracehook_report_syscall_entry (regs)) - goto skip; +if (cached_flags) { +int rc =tracehook_report_syscall_entry (regs); + +if (unlikely (cached_flags & _TIF_SYSCALL_EMU)) { +/* +* A nonzero return code from +* tracehook_report_syscall_entry() tells us +* to prevent the syscall execution, but +* we are not going to execute it anyway. +* +* Returning -1 will skip the syscall execution. +* We want to avoid clobbering any register also, +* thus, not 'gotoing' skip label. +*/ +return -1 ; + } + +if (rc) { +/* +* The tracer decided to abort the syscall. +* Note that the tracer may also just change +* regs->gpr[0] to an invalid syscall number, +* that is handled below on the exit path. +*/ + goto skip; + } + }/* Run seccomp after ptrace; allow it to set gpr[3]. */ if (do_seccomp (regs))
Signature · 1 line
ldv
Michael Ellerman
reviewerRe: [PATCH] powerpc/ptrace: cleanup do_syscall_trace_enter
Quoted 1 line · Dmitry V. Levin
Invoke
tracehook_report_syscall_entryonce.
Thanks.
Quoted 10 lines
Signed-off-by Dmitry V. Levin <[email protected]>--- arch/powerpc/kernel/ptrace.c | 54 +++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 23 deletions(-)arch/powerpc/kernel/ptrace.c +0
-0
arch/powerpc/kernel/ptrace.c static inline int do_seccomp(struct pt_regs *regs) { return 0; } · line 3267
Quoted 5 lines
arch/powerpc/kernel/ptrace.c +2
-0@@ -3263,32 +3263,40 @@ static inline int do_seccomp(struct pt_regs *regs) { return 0; }*/ long do_syscall_trace_enter (struct pt_regs *regs) { +u32 cached_flags; +
Do you mind if I just call it "flags", I find "cached_flags" a bit unwieldy for some reason.
I'm happy to fix it up when applying.
cheers
Quoted 60 lines
arch/powerpc/kernel/ptrace.c +29
-23user_exit (); -if (test_thread_flag (TIF_SYSCALL_EMU )) { -/* -* A nonzero return code from tracehook_report_syscall_entry() -* tells us to prevent the syscall execution, but we are not -* going to execute it anyway. -* -* Returning -1 will skip the syscall execution. We want to -* avoid clobbering any register also, thus, not 'gotoing' -* skip label. -*/ -if (tracehook_report_syscall_entry (regs)) - ; -return -1 ; - } + cached_flags =READ_ONCE (current_thread_info ()->flags) & + (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE); -/* -* The tracer may decide to abort the syscall, if so tracehook -* will return !0. Note that the tracer may also just change -* regs->gpr[0] to an invalid syscall number, that is handled -* below on the exit path. -*/ -if (test_thread_flag (TIF_SYSCALL_TRACE ) && -tracehook_report_syscall_entry (regs)) - goto skip; +if (cached_flags) { +int rc =tracehook_report_syscall_entry (regs); + +if (unlikely (cached_flags & _TIF_SYSCALL_EMU)) { +/* +* A nonzero return code from +* tracehook_report_syscall_entry() tells us +* to prevent the syscall execution, but +* we are not going to execute it anyway. +* +* Returning -1 will skip the syscall execution. +* We want to avoid clobbering any register also, +* thus, not 'gotoing' skip label. +*/ +return -1 ; + } + +if (rc) { +/* +* The tracer decided to abort the syscall. +* Note that the tracer may also just change +* regs->gpr[0] to an invalid syscall number, +* that is handled below on the exit path. +*/ + goto skip; + } + }/* Run seccomp after ptrace; allow it to set gpr[3]. */ if (do_seccomp (regs))Signature · 1 line
ldv
Re: [PATCH] powerpc/ptrace: cleanup do_syscall_trace_enter
Hi,
Quoted 24 lines · Michael Ellerman
Quoted 1 line · Dmitry V. Levin
Invoke
tracehook_report_syscall_entryonce.Thanks.
Quoted 10 lines
Signed-off-by Dmitry V. Levin <[email protected]>--- arch/powerpc/kernel/ptrace.c | 54 +++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 23 deletions(-)arch/powerpc/kernel/ptrace.c +0
-0arch/powerpc/kernel/ptrace.c static inline int do_seccomp(struct pt_regs *regs) { return 0; } · line 3267
Quoted 5 lines
arch/powerpc/kernel/ptrace.c +2
-0@@ -3263,32 +3263,40 @@ static inline int do_seccomp(struct pt_regs *regs) { return 0; }*/ long do_syscall_trace_enter (struct pt_regs *regs) { +u32 cached_flags; +Do you mind if I just call it "flags", I find "
cached_flags" a bit unwieldy for some reason.
Quoted 1 line
I'm happy to fix it up when applying.
No problem, feel free to call it whatever you like. Thanks,
Signature · 1 line
ldv
Oleg Nesterov
maintainerRe: [PATCH] powerpc/ptrace: cleanup do_syscall_trace_enter
In reply to Dmitry V. LevinQuoted 50 lines · Dmitry V. Levin
long
do_syscall_trace_enter(struct pt_regs *regs){arch/powerpc/kernel/ptrace.c +21
-23+u32 cached_flags; +user_exit (); -if (test_thread_flag (TIF_SYSCALL_EMU )) { -/* -* A nonzero return code from tracehook_report_syscall_entry() -* tells us to prevent the syscall execution, but we are not -* going to execute it anyway. -* -* Returning -1 will skip the syscall execution. We want to -* avoid clobbering any register also, thus, not 'gotoing' -* skip label. -*/ -if (tracehook_report_syscall_entry (regs)) - ; -return -1 ; - } + cached_flags =READ_ONCE (current_thread_info ()->flags) & + (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE); -/* -* The tracer may decide to abort the syscall, if so tracehook -* will return !0. Note that the tracer may also just change -* regs->gpr[0] to an invalid syscall number, that is handled -* below on the exit path. -*/ -if (test_thread_flag (TIF_SYSCALL_TRACE ) && -tracehook_report_syscall_entry (regs)) - goto skip; +if (cached_flags) { +int rc =tracehook_report_syscall_entry (regs); + +if (unlikely (cached_flags & _TIF_SYSCALL_EMU)) { +/* +* A nonzero return code from +* tracehook_report_syscall_entry() tells us +* to prevent the syscall execution, but +* we are not going to execute it anyway. +* +* Returning -1 will skip the syscall execution. +* We want to avoid clobbering any register also, +* thus, not 'gotoing' skip label. +*/ +return -1 ; + } +
arch/powerpc/kernel/ptrace.c static inline int do_seccomp(struct pt_regs *regs) { return 0; } · line 3299
Quoted 10 lines
arch/powerpc/kernel/ptrace.c +10
-0+if (rc) { +/* +* The tracer decided to abort the syscall. +* Note that the tracer may also just change +* regs->gpr[0] to an invalid syscall number, +* that is handled below on the exit path. +*/ + goto skip; + } + }
Looks good to me,
Oleg.
Michael Ellerman
AppliedRe: powerpc/ptrace: cleanup do_syscall_trace_enter
In reply to Dmitry V. LevinQuoted 3 lines · Dmitry V. Levin
Invoke
tracehook_report_syscall_entryonce.Signed-off-by Dmitry V. Levin <[email protected]>
Applied to powerpc next, thanks.
https://git.kernel.org/powerpc/c/8dbdec0bcb416d0ef0bfd737620d08
cheers
Michael Ellerman
AppliedQuoted 9 lines · Dmitry V. Levin
From: Elvira Khabirova <[email protected]>
Arch code should use tracehook_*() helpers, as documented in
include/linux/tracehook.h,ptrace_report_syscall()is not expected to be used outside that file.The patch does not look very nice, but at least it is correct and opens the way for
PTRACE_GET_SYSCALL_INFOAPI.
Quoted 12 lines
Co-authored-by Dmitry V. Levin <[email protected]>Fixes 5521eb4bca2d ("powerpc/ptrace: Add support for PTRACE_SYSEMU")Cc Michael Ellerman <[email protected]>Cc Benjamin Herrenschmidt <[email protected]>Cc Paul Mackerras <[email protected]>Cc Oleg Nesterov <[email protected]>Cc Breno Leitao <[email protected]>Cc Andy Lutomirski <[email protected]>Cc Eugene Syromyatnikov <[email protected]>Signed-off-by Elvira Khabirova <[email protected]>Signed-off-by Dmitry V. Levin <[email protected]>
Applied to powerpc fixes, thanks.
https://git.kernel.org/powerpc/c/a225f1567405558fb5410e9b2b9080
cheers
Oleg Nesterov
maintainerQuoted 10 lines · Dmitry V. Levin
Quoted 3 lines · Michael Ellerman
Quoted 1 line
Sorry, this patch does not work, please ignore it.
Hmm OK. Why exactly?
Unfortunately, I have no idea why it doesn't work.
All I can say is it breaks strace because the kernel no longer sends syscall entry stops.
May be because TIF_SYSCALL_EMU/etc is a bit number, not a mask? IOW, rather than
whatever & TIF_XXX
you should do
whatever & _TIF_XXX
intstead?
Oleg.
Quoted 14 lines · Oleg Nesterov
Quoted 9 lines · Dmitry V. Levin
Quoted 3 lines · Michael Ellerman
Quoted 1 line
Sorry, this patch does not work, please ignore it.
Hmm OK. Why exactly?
Unfortunately, I have no idea why it doesn't work.
All I can say is it breaks strace because the kernel no longer sends syscall entry stops.May be because TIF_SYSCALL_EMU/etc is a bit number, not a mask? IOW, rather than
Quoted 7 lines
whatever &
TIF_XXXyou should do
whatever &
_TIF_XXXintstead?
Thanks Oleg, this was exactly the reason why it didn't work.
That kind of things happens when you let userspace people hack you kernel. :)
Signature · 1 line
ldv