[PATCH 2/3] ARM: add TRACEHOOK support
Steven Walter
stevenrwalter at gmail.com
Tue Nov 29 12:51:43 EST 2011
On Tue, Nov 29, 2011 at 12:04 PM, Will Deacon <will.deacon at arm.com> wrote:
> Hi Steven,
>
> On Tue, Nov 29, 2011 at 04:28:14PM +0000, Steven Walter wrote:
>> diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
>> index 9726006..1411848 100644
>> --- a/arch/arm/kernel/ptrace.c
>> +++ b/arch/arm/kernel/ptrace.c
>> @@ -22,6 +22,7 @@
>> #include <linux/perf_event.h>
>> #include <linux/hw_breakpoint.h>
>> #include <linux/regset.h>
>> +#include <linux/tracehook.h>
>>
>> #include <asm/pgtable.h>
>> #include <asm/system.h>
>> @@ -928,8 +929,6 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
>>
>> if (!test_thread_flag(TIF_SYSCALL_TRACE))
>> return scno;
>> - if (!(current->ptrace & PT_PTRACED))
>> - return scno;
>
> This means that we can potentially corrupt current_thread_info()->syscall
> for tasks that aren't being traced. I don't think that matters as it's only
> used by ptrace, but worth bearing in mind.
Is it valid for a process to have TIF_SYSCALL_TRACE set but not
PT_PTRACED? Given that they were checking both before, one might
assume so, but I don't really know what that would mean.
>> /*
>> * Save IP. IP is used to denote syscall entry/exit:
>> @@ -940,19 +939,13 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
>>
>> current_thread_info()->syscall = scno;
>>
>> - /* the 0x80 provides a way for the tracing parent to distinguish
>> - between a syscall stop and SIGTRAP delivery */
>> - ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
>> - ? 0x80 : 0));
>> - /*
>> - * this isn't the same as continuing with a signal, but it will do
>> - * for normal use. strace only continues with a signal if the
>> - * stopping signal is not SIGTRAP. -brl
>> - */
>> - if (current->exit_code) {
>> - send_sig(current->exit_code, current, 1);
>> - current->exit_code = 0;
>> + if (why == 0) {
>> + if (tracehook_report_syscall_entry(regs))
>> + current_thread_info()->syscall = -1;
>
> Why do you set syscall to -1 here? It looks like
> tracehook_report_syscall_entry always returns 0, but even so, I'm not sure
> what this -1 represents. You could also rewrite this a bit more neatly:
tracehook_report_syscall_entry is marked __must_check, and the comment
says that if it returns non-zero the arch could should abort the
system call. x86 just returns -1 from its trace function in that
case, so I took the same approach. In particular, if we treat -1 as
the system call number, the system call should fail with ENOSYS, which
include/linux/tracehook.h says is acceptable.
> if (why)
> tracehook_report_syscall_exit(...);
> else
> tracehook_report_syscall_entry(...);
Agreed, will fix
>> + } else {
>> + tracehook_report_syscall_exit(regs, 0);
>> }
>> +
>> regs->ARM_ip = ip;
>>
>> return current_thread_info()->syscall;
>> diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
>> index 0340224..26c26f5 100644
>> --- a/arch/arm/kernel/signal.c
>> +++ b/arch/arm/kernel/signal.c
>> @@ -645,6 +645,8 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
>> recalc_sigpending();
>> spin_unlock_irq(&tsk->sighand->siglock);
>>
>> + tracehook_signal_handler(sig, info, ka, regs, 0);
>> +
>
> This doesn't appear to do anything but I guess that's where it should live.
Right, I just added it because arch/Kconfig said to :-)
--
-Steven Walter <stevenrwalter at gmail.com>
More information about the linux-arm-kernel
mailing list