diff options
author | Jeff Dike <jdike@addtoit.com> | 2007-05-23 16:57:40 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-23 23:14:12 -0400 |
commit | cf6acedbeac17dea1c1eed85048a72e188f3f768 (patch) | |
tree | d5c1b4e5b9a5e8c22198bc92839c80305641cb09 | |
parent | da90fa8ff671a0139772ec3b3e82c06077e82122 (diff) |
uml: improve PTRACE_SYSEMU checking
Make the PTRACE_SYSEMU checking more robust. It will make sure that system
call numbers are reported correctly. If there is a problem, it will disable
PTRACE_SYSEMU use and use PTRACE_SYSCALL instead.
Thanks to Balaji G for helping reproduce this problem.
Signed-off-by: Jeff Dike <jdike@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | arch/um/os-Linux/start_up.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 79471f85eb89..3fc13fa8729d 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c | |||
@@ -144,9 +144,7 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode, | |||
144 | int exit_with = WEXITSTATUS(status); | 144 | int exit_with = WEXITSTATUS(status); |
145 | if (exit_with == 2) | 145 | if (exit_with == 2) |
146 | non_fatal("check_ptrace : child exited with status 2. " | 146 | non_fatal("check_ptrace : child exited with status 2. " |
147 | "Serious trouble happening! Try updating " | 147 | "\nDisabling SYSEMU support.\n"); |
148 | "your host skas patch!\nDisabling SYSEMU " | ||
149 | "support."); | ||
150 | non_fatal("check_ptrace : child exited with exitcode %d, while " | 148 | non_fatal("check_ptrace : child exited with exitcode %d, while " |
151 | "expecting %d; status 0x%x\n", exit_with, | 149 | "expecting %d; status 0x%x\n", exit_with, |
152 | exitcode, status); | 150 | exitcode, status); |
@@ -209,6 +207,7 @@ __uml_setup("nosysemu", nosysemu_cmd_param, | |||
209 | static void __init check_sysemu(void) | 207 | static void __init check_sysemu(void) |
210 | { | 208 | { |
211 | void *stack; | 209 | void *stack; |
210 | unsigned long regs[MAX_REG_NR]; | ||
212 | int pid, n, status, count=0; | 211 | int pid, n, status, count=0; |
213 | 212 | ||
214 | non_fatal("Checking syscall emulation patch for ptrace..."); | 213 | non_fatal("Checking syscall emulation patch for ptrace..."); |
@@ -225,11 +224,20 @@ static void __init check_sysemu(void) | |||
225 | fatal("check_sysemu : expected SIGTRAP, got status = %d", | 224 | fatal("check_sysemu : expected SIGTRAP, got status = %d", |
226 | status); | 225 | status); |
227 | 226 | ||
228 | n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, | 227 | if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) |
229 | os_getpid()); | 228 | fatal_perror("check_sysemu : PTRACE_GETREGS failed"); |
230 | if(n < 0) | 229 | if(PT_SYSCALL_NR(regs) != __NR_getpid){ |
231 | fatal_perror("check_sysemu : failed to modify system call " | 230 | non_fatal("check_sysemu got system call number %d, " |
232 | "return"); | 231 | "expected %d...", PT_SYSCALL_NR(regs), __NR_getpid); |
232 | goto fail; | ||
233 | } | ||
234 | |||
235 | n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, os_getpid()); | ||
236 | if(n < 0){ | ||
237 | non_fatal("check_sysemu : failed to modify system call " | ||
238 | "return"); | ||
239 | goto fail; | ||
240 | } | ||
233 | 241 | ||
234 | if (stop_ptraced_child(pid, stack, 0, 0) < 0) | 242 | if (stop_ptraced_child(pid, stack, 0, 0) < 0) |
235 | goto fail_stopped; | 243 | goto fail_stopped; |