diff options
| -rw-r--r-- | arch/arm/kernel/entry-common.S | 14 | ||||
| -rw-r--r-- | arch/arm/kernel/ptrace.c | 37 |
2 files changed, 31 insertions, 20 deletions
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 10911c93fbf1..49d9f9305247 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S | |||
| @@ -442,10 +442,9 @@ ENDPROC(vector_swi) | |||
| 442 | * context switches, and waiting for our parent to respond. | 442 | * context switches, and waiting for our parent to respond. |
| 443 | */ | 443 | */ |
| 444 | __sys_trace: | 444 | __sys_trace: |
| 445 | mov r2, scno | 445 | mov r1, scno |
| 446 | add r1, sp, #S_OFF | 446 | add r0, sp, #S_OFF |
| 447 | mov r0, #0 @ trace entry [IP = 0] | 447 | bl syscall_trace_enter |
| 448 | bl syscall_trace | ||
| 449 | 448 | ||
| 450 | adr lr, BSYM(__sys_trace_return) @ return address | 449 | adr lr, BSYM(__sys_trace_return) @ return address |
| 451 | mov scno, r0 @ syscall number (possibly new) | 450 | mov scno, r0 @ syscall number (possibly new) |
| @@ -457,10 +456,9 @@ __sys_trace: | |||
| 457 | 456 | ||
| 458 | __sys_trace_return: | 457 | __sys_trace_return: |
| 459 | str r0, [sp, #S_R0 + S_OFF]! @ save returned r0 | 458 | str r0, [sp, #S_R0 + S_OFF]! @ save returned r0 |
| 460 | mov r2, scno | 459 | mov r1, scno |
| 461 | mov r1, sp | 460 | mov r0, sp |
| 462 | mov r0, #1 @ trace exit [IP = 1] | 461 | bl syscall_trace_exit |
| 463 | bl syscall_trace | ||
| 464 | b ret_slow_syscall | 462 | b ret_slow_syscall |
| 465 | 463 | ||
| 466 | .align 5 | 464 | .align 5 |
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 592a39d0ef31..dab711e6e1ca 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c | |||
| @@ -907,12 +907,18 @@ long arch_ptrace(struct task_struct *child, long request, | |||
| 907 | return ret; | 907 | return ret; |
| 908 | } | 908 | } |
| 909 | 909 | ||
| 910 | asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno) | 910 | enum ptrace_syscall_dir { |
| 911 | PTRACE_SYSCALL_ENTER = 0, | ||
| 912 | PTRACE_SYSCALL_EXIT, | ||
| 913 | }; | ||
| 914 | |||
| 915 | static int ptrace_syscall_trace(struct pt_regs *regs, int scno, | ||
| 916 | enum ptrace_syscall_dir dir) | ||
| 911 | { | 917 | { |
| 912 | unsigned long ip; | 918 | unsigned long ip; |
| 913 | 919 | ||
| 914 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) | 920 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) |
| 915 | goto out_no_trace; | 921 | return scno; |
| 916 | 922 | ||
| 917 | current_thread_info()->syscall = scno; | 923 | current_thread_info()->syscall = scno; |
| 918 | 924 | ||
| @@ -921,21 +927,28 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno) | |||
| 921 | * IP = 0 -> entry, =1 -> exit | 927 | * IP = 0 -> entry, =1 -> exit |
| 922 | */ | 928 | */ |
| 923 | ip = regs->ARM_ip; | 929 | ip = regs->ARM_ip; |
| 924 | regs->ARM_ip = why; | 930 | regs->ARM_ip = dir; |
| 925 | 931 | ||
| 926 | if (why) | 932 | if (dir == PTRACE_SYSCALL_EXIT) |
| 927 | tracehook_report_syscall_exit(regs, 0); | 933 | tracehook_report_syscall_exit(regs, 0); |
| 928 | else if (tracehook_report_syscall_entry(regs)) | 934 | else if (tracehook_report_syscall_entry(regs)) |
| 929 | current_thread_info()->syscall = -1; | 935 | current_thread_info()->syscall = -1; |
| 930 | 936 | ||
| 931 | regs->ARM_ip = ip; | 937 | regs->ARM_ip = ip; |
| 932 | scno = current_thread_info()->syscall; | 938 | return current_thread_info()->syscall; |
| 939 | } | ||
| 933 | 940 | ||
| 934 | out_no_trace: | 941 | asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno) |
| 935 | if (why) | 942 | { |
| 936 | audit_syscall_exit(regs); | 943 | int ret = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_ENTER); |
| 937 | else | 944 | audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1, |
| 938 | audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, | 945 | regs->ARM_r2, regs->ARM_r3); |
| 939 | regs->ARM_r1, regs->ARM_r2, regs->ARM_r3); | 946 | return ret; |
| 940 | return scno; | 947 | } |
| 948 | |||
| 949 | asmlinkage int syscall_trace_exit(struct pt_regs *regs, int scno) | ||
| 950 | { | ||
| 951 | int ret = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_EXIT); | ||
| 952 | audit_syscall_exit(regs); | ||
| 953 | return ret; | ||
| 941 | } | 954 | } |
