diff options
Diffstat (limited to 'arch/powerpc/kernel/ptrace.c')
-rw-r--r-- | arch/powerpc/kernel/ptrace.c | 54 |
1 files changed, 31 insertions, 23 deletions
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 714c3480c52d..cdd5d1d3ae41 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c | |||
@@ -3263,32 +3263,40 @@ static inline int do_seccomp(struct pt_regs *regs) { return 0; } | |||
3263 | */ | 3263 | */ |
3264 | long do_syscall_trace_enter(struct pt_regs *regs) | 3264 | long do_syscall_trace_enter(struct pt_regs *regs) |
3265 | { | 3265 | { |
3266 | u32 flags; | ||
3267 | |||
3266 | user_exit(); | 3268 | user_exit(); |
3267 | 3269 | ||
3268 | if (test_thread_flag(TIF_SYSCALL_EMU)) { | 3270 | flags = READ_ONCE(current_thread_info()->flags) & |
3269 | /* | 3271 | (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE); |
3270 | * A nonzero return code from tracehook_report_syscall_entry() | ||
3271 | * tells us to prevent the syscall execution, but we are not | ||
3272 | * going to execute it anyway. | ||
3273 | * | ||
3274 | * Returning -1 will skip the syscall execution. We want to | ||
3275 | * avoid clobbering any register also, thus, not 'gotoing' | ||
3276 | * skip label. | ||
3277 | */ | ||
3278 | if (tracehook_report_syscall_entry(regs)) | ||
3279 | ; | ||
3280 | return -1; | ||
3281 | } | ||
3282 | 3272 | ||
3283 | /* | 3273 | if (flags) { |
3284 | * The tracer may decide to abort the syscall, if so tracehook | 3274 | int rc = tracehook_report_syscall_entry(regs); |
3285 | * will return !0. Note that the tracer may also just change | 3275 | |
3286 | * regs->gpr[0] to an invalid syscall number, that is handled | 3276 | if (unlikely(flags & _TIF_SYSCALL_EMU)) { |
3287 | * below on the exit path. | 3277 | /* |
3288 | */ | 3278 | * A nonzero return code from |
3289 | if (test_thread_flag(TIF_SYSCALL_TRACE) && | 3279 | * tracehook_report_syscall_entry() tells us to prevent |
3290 | tracehook_report_syscall_entry(regs)) | 3280 | * the syscall execution, but we are not going to |
3291 | goto skip; | 3281 | * execute it anyway. |
3282 | * | ||
3283 | * Returning -1 will skip the syscall execution. We want | ||
3284 | * to avoid clobbering any registers, so we don't goto | ||
3285 | * the skip label below. | ||
3286 | */ | ||
3287 | return -1; | ||
3288 | } | ||
3289 | |||
3290 | if (rc) { | ||
3291 | /* | ||
3292 | * The tracer decided to abort the syscall. Note that | ||
3293 | * the tracer may also just change regs->gpr[0] to an | ||
3294 | * invalid syscall number, that is handled below on the | ||
3295 | * exit path. | ||
3296 | */ | ||
3297 | goto skip; | ||
3298 | } | ||
3299 | } | ||
3292 | 3300 | ||
3293 | /* Run seccomp after ptrace; allow it to set gpr[3]. */ | 3301 | /* Run seccomp after ptrace; allow it to set gpr[3]. */ |
3294 | if (do_seccomp(regs)) | 3302 | if (do_seccomp(regs)) |