diff options
-rw-r--r-- | arch/x86_64/ia32/ptrace32.c | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/arch/x86_64/ia32/ptrace32.c b/arch/x86_64/ia32/ptrace32.c index 23a4515a73b4..4defe63f5916 100644 --- a/arch/x86_64/ia32/ptrace32.c +++ b/arch/x86_64/ia32/ptrace32.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <asm/debugreg.h> | 27 | #include <asm/debugreg.h> |
28 | #include <asm/i387.h> | 28 | #include <asm/i387.h> |
29 | #include <asm/fpu32.h> | 29 | #include <asm/fpu32.h> |
30 | #include <asm/ia32.h> | ||
30 | 31 | ||
31 | /* | 32 | /* |
32 | * Determines which flags the user has access to [1 = access, 0 = no access]. | 33 | * Determines which flags the user has access to [1 = access, 0 = no access]. |
@@ -199,6 +200,24 @@ static int getreg32(struct task_struct *child, unsigned regno, u32 *val) | |||
199 | 200 | ||
200 | #undef R32 | 201 | #undef R32 |
201 | 202 | ||
203 | static long ptrace32_siginfo(unsigned request, u32 pid, u32 addr, u32 data) | ||
204 | { | ||
205 | int ret; | ||
206 | compat_siginfo_t *si32 = (compat_siginfo_t *)compat_ptr(data); | ||
207 | siginfo_t *si = compat_alloc_user_space(sizeof(siginfo_t)); | ||
208 | if (request == PTRACE_SETSIGINFO) { | ||
209 | ret = copy_siginfo_from_user32(si, si32); | ||
210 | if (ret) | ||
211 | return ret; | ||
212 | } | ||
213 | ret = sys_ptrace(request, pid, addr, (unsigned long)si); | ||
214 | if (ret) | ||
215 | return ret; | ||
216 | if (request == PTRACE_GETSIGINFO) | ||
217 | ret = copy_siginfo_to_user32(si32, si); | ||
218 | return ret; | ||
219 | } | ||
220 | |||
202 | asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) | 221 | asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) |
203 | { | 222 | { |
204 | struct task_struct *child; | 223 | struct task_struct *child; |
@@ -208,9 +227,19 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) | |||
208 | __u32 val; | 227 | __u32 val; |
209 | 228 | ||
210 | switch (request) { | 229 | switch (request) { |
211 | default: | 230 | case PTRACE_TRACEME: |
231 | case PTRACE_ATTACH: | ||
232 | case PTRACE_KILL: | ||
233 | case PTRACE_CONT: | ||
234 | case PTRACE_SINGLESTEP: | ||
235 | case PTRACE_DETACH: | ||
236 | case PTRACE_SYSCALL: | ||
237 | case PTRACE_SETOPTIONS: | ||
212 | return sys_ptrace(request, pid, addr, data); | 238 | return sys_ptrace(request, pid, addr, data); |
213 | 239 | ||
240 | default: | ||
241 | return -EINVAL; | ||
242 | |||
214 | case PTRACE_PEEKTEXT: | 243 | case PTRACE_PEEKTEXT: |
215 | case PTRACE_PEEKDATA: | 244 | case PTRACE_PEEKDATA: |
216 | case PTRACE_POKEDATA: | 245 | case PTRACE_POKEDATA: |
@@ -225,10 +254,11 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) | |||
225 | case PTRACE_GETFPXREGS: | 254 | case PTRACE_GETFPXREGS: |
226 | case PTRACE_GETEVENTMSG: | 255 | case PTRACE_GETEVENTMSG: |
227 | break; | 256 | break; |
228 | } | ||
229 | 257 | ||
230 | if (request == PTRACE_TRACEME) | 258 | case PTRACE_SETSIGINFO: |
231 | return ptrace_traceme(); | 259 | case PTRACE_GETSIGINFO: |
260 | return ptrace32_siginfo(request, pid, addr, data); | ||
261 | } | ||
232 | 262 | ||
233 | child = ptrace_get_task_struct(pid); | 263 | child = ptrace_get_task_struct(pid); |
234 | if (IS_ERR(child)) | 264 | if (IS_ERR(child)) |
@@ -349,8 +379,7 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) | |||
349 | break; | 379 | break; |
350 | 380 | ||
351 | default: | 381 | default: |
352 | ret = -EINVAL; | 382 | BUG(); |
353 | break; | ||
354 | } | 383 | } |
355 | 384 | ||
356 | out: | 385 | out: |