aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/um/kernel/process.c48
1 files changed, 19 insertions, 29 deletions
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index 793c77c6ef9c..1b5ef3e96c71 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -130,7 +130,7 @@ int start_fork_tramp(void *thread_arg, unsigned long temp_stack,
130 return(arg.pid); 130 return(arg.pid);
131} 131}
132 132
133static int ptrace_child(void *arg) 133static int ptrace_child(void)
134{ 134{
135 int ret; 135 int ret;
136 int pid = os_getpid(), ppid = getppid(); 136 int pid = os_getpid(), ppid = getppid();
@@ -159,20 +159,16 @@ static int ptrace_child(void *arg)
159 _exit(ret); 159 _exit(ret);
160} 160}
161 161
162static int start_ptraced_child(void **stack_out) 162static int start_ptraced_child(void)
163{ 163{
164 void *stack;
165 unsigned long sp;
166 int pid, n, status; 164 int pid, n, status;
167 165
168 stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, 166 pid = fork();
169 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 167 if(pid == 0)
170 if(stack == MAP_FAILED) 168 ptrace_child();
171 panic("check_ptrace : mmap failed, errno = %d", errno); 169
172 sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
173 pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
174 if(pid < 0) 170 if(pid < 0)
175 panic("check_ptrace : clone failed, errno = %d", errno); 171 panic("check_ptrace : fork failed, errno = %d", errno);
176 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 172 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
177 if(n < 0) 173 if(n < 0)
178 panic("check_ptrace : wait failed, errno = %d", errno); 174 panic("check_ptrace : wait failed, errno = %d", errno);
@@ -180,7 +176,6 @@ static int start_ptraced_child(void **stack_out)
180 panic("check_ptrace : expected SIGSTOP, got status = %d", 176 panic("check_ptrace : expected SIGSTOP, got status = %d",
181 status); 177 status);
182 178
183 *stack_out = stack;
184 return(pid); 179 return(pid);
185} 180}
186 181
@@ -188,12 +183,12 @@ static int start_ptraced_child(void **stack_out)
188 * just avoid using sysemu, not panic, but only if SYSEMU features are broken. 183 * just avoid using sysemu, not panic, but only if SYSEMU features are broken.
189 * So only for SYSEMU features we test mustpanic, while normal host features 184 * So only for SYSEMU features we test mustpanic, while normal host features
190 * must work anyway!*/ 185 * must work anyway!*/
191static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic) 186static int stop_ptraced_child(int pid, int exitcode, int mustexit)
192{ 187{
193 int status, n, ret = 0; 188 int status, n, ret = 0;
194 189
195 if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) 190 if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
196 panic("check_ptrace : ptrace failed, errno = %d", errno); 191 panic("stop_ptraced_child : ptrace failed, errno = %d", errno);
197 CATCH_EINTR(n = waitpid(pid, &status, 0)); 192 CATCH_EINTR(n = waitpid(pid, &status, 0));
198 if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { 193 if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) {
199 int exit_with = WEXITSTATUS(status); 194 int exit_with = WEXITSTATUS(status);
@@ -204,15 +199,13 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic)
204 printk("check_ptrace : child exited with exitcode %d, while " 199 printk("check_ptrace : child exited with exitcode %d, while "
205 "expecting %d; status 0x%x", exit_with, 200 "expecting %d; status 0x%x", exit_with,
206 exitcode, status); 201 exitcode, status);
207 if (mustpanic) 202 if (mustexit)
208 panic("\n"); 203 panic("\n");
209 else 204 else
210 printk("\n"); 205 printk("\n");
211 ret = -1; 206 ret = -1;
212 } 207 }
213 208
214 if(munmap(stack, PAGE_SIZE) < 0)
215 panic("check_ptrace : munmap failed, errno = %d", errno);
216 return ret; 209 return ret;
217} 210}
218 211
@@ -234,12 +227,11 @@ __uml_setup("nosysemu", nosysemu_cmd_param,
234 227
235static void __init check_sysemu(void) 228static void __init check_sysemu(void)
236{ 229{
237 void *stack;
238 int pid, syscall, n, status, count=0; 230 int pid, syscall, n, status, count=0;
239 231
240 printk("Checking syscall emulation patch for ptrace..."); 232 printk("Checking syscall emulation patch for ptrace...");
241 sysemu_supported = 0; 233 sysemu_supported = 0;
242 pid = start_ptraced_child(&stack); 234 pid = start_ptraced_child();
243 235
244 if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) 236 if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0)
245 goto fail; 237 goto fail;
@@ -257,7 +249,7 @@ static void __init check_sysemu(void)
257 panic("check_sysemu : failed to modify system " 249 panic("check_sysemu : failed to modify system "
258 "call return, errno = %d", errno); 250 "call return, errno = %d", errno);
259 251
260 if (stop_ptraced_child(pid, stack, 0, 0) < 0) 252 if (stop_ptraced_child(pid, 0, 0) < 0)
261 goto fail_stopped; 253 goto fail_stopped;
262 254
263 sysemu_supported = 1; 255 sysemu_supported = 1;
@@ -265,7 +257,7 @@ static void __init check_sysemu(void)
265 set_using_sysemu(!force_sysemu_disabled); 257 set_using_sysemu(!force_sysemu_disabled);
266 258
267 printk("Checking advanced syscall emulation patch for ptrace..."); 259 printk("Checking advanced syscall emulation patch for ptrace...");
268 pid = start_ptraced_child(&stack); 260 pid = start_ptraced_child();
269 while(1){ 261 while(1){
270 count++; 262 count++;
271 if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) 263 if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0)
@@ -290,7 +282,7 @@ static void __init check_sysemu(void)
290 break; 282 break;
291 } 283 }
292 } 284 }
293 if (stop_ptraced_child(pid, stack, 0, 0) < 0) 285 if (stop_ptraced_child(pid, 0, 0) < 0)
294 goto fail_stopped; 286 goto fail_stopped;
295 287
296 sysemu_supported = 2; 288 sysemu_supported = 2;
@@ -301,18 +293,17 @@ static void __init check_sysemu(void)
301 return; 293 return;
302 294
303fail: 295fail:
304 stop_ptraced_child(pid, stack, 1, 0); 296 stop_ptraced_child(pid, 1, 0);
305fail_stopped: 297fail_stopped:
306 printk("missing\n"); 298 printk("missing\n");
307} 299}
308 300
309void __init check_ptrace(void) 301void __init check_ptrace(void)
310{ 302{
311 void *stack;
312 int pid, syscall, n, status; 303 int pid, syscall, n, status;
313 304
314 printk("Checking that ptrace can change system call numbers..."); 305 printk("Checking that ptrace can change system call numbers...");
315 pid = start_ptraced_child(&stack); 306 pid = start_ptraced_child();
316 307
317 if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) 308 if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
318 panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno); 309 panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno);
@@ -339,7 +330,7 @@ void __init check_ptrace(void)
339 break; 330 break;
340 } 331 }
341 } 332 }
342 stop_ptraced_child(pid, stack, 0, 1); 333 stop_ptraced_child(pid, 0, 1);
343 printk("OK\n"); 334 printk("OK\n");
344 check_sysemu(); 335 check_sysemu();
345} 336}
@@ -371,11 +362,10 @@ void forward_pending_sigio(int target)
371static inline int check_skas3_ptrace_support(void) 362static inline int check_skas3_ptrace_support(void)
372{ 363{
373 struct ptrace_faultinfo fi; 364 struct ptrace_faultinfo fi;
374 void *stack;
375 int pid, n, ret = 1; 365 int pid, n, ret = 1;
376 366
377 printf("Checking for the skas3 patch in the host..."); 367 printf("Checking for the skas3 patch in the host...");
378 pid = start_ptraced_child(&stack); 368 pid = start_ptraced_child();
379 369
380 n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); 370 n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
381 if (n < 0) { 371 if (n < 0) {
@@ -390,7 +380,7 @@ static inline int check_skas3_ptrace_support(void)
390 } 380 }
391 381
392 init_registers(pid); 382 init_registers(pid);
393 stop_ptraced_child(pid, stack, 1, 1); 383 stop_ptraced_child(pid, 1, 1);
394 384
395 return(ret); 385 return(ret);
396} 386}