aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2007-05-23 16:57:40 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-23 23:14:12 -0400
commitcf6acedbeac17dea1c1eed85048a72e188f3f768 (patch)
treed5c1b4e5b9a5e8c22198bc92839c80305641cb09
parentda90fa8ff671a0139772ec3b3e82c06077e82122 (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.c24
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,
209static void __init check_sysemu(void) 207static 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;