diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/um/include/asm/ptrace-generic.h | 2 | ||||
-rw-r--r-- | arch/um/kernel/ptrace.c | 71 | ||||
-rw-r--r-- | arch/um/kernel/skas/syscall.c | 4 |
3 files changed, 34 insertions, 43 deletions
diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h index e786a6a3ec5e..442f1d025dc2 100644 --- a/arch/um/include/asm/ptrace-generic.h +++ b/arch/um/include/asm/ptrace-generic.h | |||
@@ -37,6 +37,8 @@ extern int putreg(struct task_struct *child, int regno, unsigned long value); | |||
37 | 37 | ||
38 | extern int arch_copy_tls(struct task_struct *new); | 38 | extern int arch_copy_tls(struct task_struct *new); |
39 | extern void clear_flushed_tls(struct task_struct *task); | 39 | extern void clear_flushed_tls(struct task_struct *task); |
40 | extern void syscall_trace_enter(struct pt_regs *regs); | ||
41 | extern void syscall_trace_leave(struct pt_regs *regs); | ||
40 | 42 | ||
41 | #endif | 43 | #endif |
42 | 44 | ||
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index 06b190390505..694d551c8899 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c | |||
@@ -3,11 +3,12 @@ | |||
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/audit.h" | 6 | #include <linux/audit.h> |
7 | #include "linux/ptrace.h" | 7 | #include <linux/ptrace.h> |
8 | #include "linux/sched.h" | 8 | #include <linux/sched.h> |
9 | #include "asm/uaccess.h" | 9 | #include <linux/tracehook.h> |
10 | #include "skas_ptrace.h" | 10 | #include <asm/uaccess.h> |
11 | #include <skas_ptrace.h> | ||
11 | 12 | ||
12 | 13 | ||
13 | 14 | ||
@@ -162,48 +163,36 @@ static void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs, | |||
162 | * XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and | 163 | * XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and |
163 | * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check | 164 | * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check |
164 | */ | 165 | */ |
165 | void syscall_trace(struct uml_pt_regs *regs, int entryexit) | 166 | void syscall_trace_enter(struct pt_regs *regs) |
166 | { | 167 | { |
167 | int is_singlestep = (current->ptrace & PT_DTRACE) && entryexit; | 168 | audit_syscall_entry(HOST_AUDIT_ARCH, |
168 | int tracesysgood; | 169 | UPT_SYSCALL_NR(®s->regs), |
169 | 170 | UPT_SYSCALL_ARG1(®s->regs), | |
170 | if (!entryexit) | 171 | UPT_SYSCALL_ARG2(®s->regs), |
171 | audit_syscall_entry(HOST_AUDIT_ARCH, | 172 | UPT_SYSCALL_ARG3(®s->regs), |
172 | UPT_SYSCALL_NR(regs), | 173 | UPT_SYSCALL_ARG4(®s->regs)); |
173 | UPT_SYSCALL_ARG1(regs), | ||
174 | UPT_SYSCALL_ARG2(regs), | ||
175 | UPT_SYSCALL_ARG3(regs), | ||
176 | UPT_SYSCALL_ARG4(regs)); | ||
177 | else | ||
178 | audit_syscall_exit(regs); | ||
179 | |||
180 | /* Fake a debug trap */ | ||
181 | if (is_singlestep) | ||
182 | send_sigtrap(current, regs, 0); | ||
183 | 174 | ||
184 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) | 175 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) |
185 | return; | 176 | return; |
186 | 177 | ||
187 | if (!(current->ptrace & PT_PTRACED)) | 178 | tracehook_report_syscall_entry(regs); |
188 | return; | 179 | } |
189 | 180 | ||
190 | /* | 181 | void syscall_trace_leave(struct pt_regs *regs) |
191 | * the 0x80 provides a way for the tracing parent to distinguish | 182 | { |
192 | * between a syscall stop and SIGTRAP delivery | 183 | int ptraced = current->ptrace; |
193 | */ | ||
194 | tracesysgood = (current->ptrace & PT_TRACESYSGOOD); | ||
195 | ptrace_notify(SIGTRAP | (tracesysgood ? 0x80 : 0)); | ||
196 | 184 | ||
197 | if (entryexit) /* force do_signal() --> is_syscall() */ | 185 | audit_syscall_exit(regs); |
198 | set_thread_flag(TIF_SIGPENDING); | ||
199 | 186 | ||
200 | /* | 187 | /* Fake a debug trap */ |
201 | * this isn't the same as continuing with a signal, but it will do | 188 | if (ptraced & PT_DTRACE) |
202 | * for normal use. strace only continues with a signal if the | 189 | send_sigtrap(current, ®s->regs, 0); |
203 | * stopping signal is not SIGTRAP. -brl | 190 | |
204 | */ | 191 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) |
205 | if (current->exit_code) { | 192 | return; |
206 | send_sig(current->exit_code, current, 1); | 193 | |
207 | current->exit_code = 0; | 194 | tracehook_report_syscall_exit(regs, 0); |
208 | } | 195 | /* force do_signal() --> is_syscall() */ |
196 | if (ptraced & PT_PTRACED) | ||
197 | set_thread_flag(TIF_SIGPENDING); | ||
209 | } | 198 | } |
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c index 800551a29dbf..86368a025a96 100644 --- a/arch/um/kernel/skas/syscall.c +++ b/arch/um/kernel/skas/syscall.c | |||
@@ -18,7 +18,7 @@ void handle_syscall(struct uml_pt_regs *r) | |||
18 | long result; | 18 | long result; |
19 | int syscall; | 19 | int syscall; |
20 | 20 | ||
21 | syscall_trace(r, 0); | 21 | syscall_trace_enter(regs); |
22 | 22 | ||
23 | /* | 23 | /* |
24 | * This should go in the declaration of syscall, but when I do that, | 24 | * This should go in the declaration of syscall, but when I do that, |
@@ -36,5 +36,5 @@ void handle_syscall(struct uml_pt_regs *r) | |||
36 | 36 | ||
37 | PT_REGS_SET_SYSCALL_RETURN(regs, result); | 37 | PT_REGS_SET_SYSCALL_RETURN(regs, result); |
38 | 38 | ||
39 | syscall_trace(r, 1); | 39 | syscall_trace_leave(regs); |
40 | } | 40 | } |