18 #include <asm/unistd.h>
22 #include <ptrace_user.h>
23 #include <registers.h>
25 #include <skas_ptrace.h>
27 static void ptrace_child(
void)
50 else if (sc_result == ppid)
66 static void fatal_perror(
const char *
str)
83 static void non_fatal(
char *
fmt, ...)
92 static int start_ptraced_child(
void)
100 fatal_perror(
"start_ptraced_child : fork failed");
104 fatal_perror(
"check_ptrace : waitpid failed");
105 if (!WIFSTOPPED(status) || (WSTOPSIG(status) !=
SIGSTOP))
106 fatal(
"check_ptrace : expected SIGSTOP, got status = %d",
118 static int stop_ptraced_child(
int pid,
int exitcode,
int mustexit)
123 perror(
"stop_ptraced_child : ptrace failed");
127 if (!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) {
128 int exit_with = WEXITSTATUS(status);
130 non_fatal(
"check_ptrace : child exited with status 2. "
131 "\nDisabling SYSEMU support.\n");
132 non_fatal(
"check_ptrace : child exited with exitcode %d, while "
133 "expecting %d; status 0x%x\n", exit_with,
145 static int disable_ptrace_faultinfo;
148 static int disable_ptrace_ldt;
151 static int disable_proc_mm;
154 static int disable_switch_mm;
160 disable_ptrace_faultinfo = 1;
161 disable_ptrace_ldt = 1;
163 disable_switch_mm = 1;
170 static int __init mode_skas0_cmd_param(
char *
str,
int*
add)
175 " Disables SKAS3 and SKAS4 usage, so that SKAS0 is used\n\n");
179 " Disables SKAS3 and SKAS4 usage, so that SKAS0 is used.\n\n");
182 static int force_sysemu_disabled = 0;
184 static int __init nosysemu_cmd_param(
char *
str,
int*
add)
186 force_sysemu_disabled = 1;
192 " Turns off syscall emulation patch for ptrace (SYSEMU) on.\n"
193 " SYSEMU is a performance-patch introduced by Laurent Vivier. It changes\n"
194 " behaviour of ptrace() and helps reducing host context switch rate.\n"
195 " To make it working, you need a kernel patch for your host, too.\n"
196 " See http://perso.wanadoo.fr/laurent.vivier/UML/ for further \n"
197 " information.\n\n");
199 static void __init check_sysemu(
void)
204 non_fatal(
"Checking syscall emulation patch for ptrace...");
206 pid = start_ptraced_child();
213 fatal_perror(
"check_sysemu : wait failed");
214 if (!WIFSTOPPED(status) || (WSTOPSIG(status) !=
SIGTRAP))
215 fatal(
"check_sysemu : expected SIGTRAP, got status = %d\n",
219 fatal_perror(
"check_sysemu : PTRACE_GETREGS failed");
221 non_fatal(
"check_sysemu got system call number %d, "
228 non_fatal(
"check_sysemu : failed to modify system call "
233 if (stop_ptraced_child(pid, 0, 0) < 0)
240 non_fatal(
"Checking advanced syscall emulation patch for ptrace...");
241 pid = start_ptraced_child();
245 fatal_perror(
"check_sysemu: PTRACE_OLDSETOPTIONS failed");
253 fatal_perror(
"check_sysemu: wait failed");
255 if (WIFSTOPPED(status) &&
256 (WSTOPSIG(status) == (
SIGTRAP|0x80))) {
258 non_fatal(
"check_sysemu: SYSEMU_SINGLESTEP "
259 "doesn't singlestep");
265 fatal_perror(
"check_sysemu : failed to modify "
266 "system call return");
269 else if (WIFSTOPPED(status) && (WSTOPSIG(status) ==
SIGTRAP))
272 non_fatal(
"check_sysemu: expected SIGTRAP or "
273 "(SIGTRAP | 0x80), got status = %d\n",
278 if (stop_ptraced_child(pid, 0, 0) < 0)
284 if (!force_sysemu_disabled)
289 stop_ptraced_child(pid, 1, 0);
291 non_fatal(
"missing\n");
294 static void __init check_ptrace(
void)
298 non_fatal(
"Checking that ptrace can change system call numbers...");
299 pid = start_ptraced_child();
303 fatal_perror(
"check_ptrace: PTRACE_OLDSETOPTIONS failed");
307 fatal_perror(
"check_ptrace : ptrace failed");
311 fatal_perror(
"check_ptrace : wait failed");
313 if (!WIFSTOPPED(status) ||
314 (WSTOPSIG(status) != (
SIGTRAP | 0x80)))
315 fatal(
"check_ptrace : expected (SIGTRAP|0x80), "
316 "got status = %d", status);
324 fatal_perror(
"check_ptrace : failed to modify "
329 stop_ptraced_child(pid, 0, 1);
336 static void __init check_coredump_limit(
void)
342 perror(
"Getting core dump limit");
346 printf(
"Core dump limits :\n\tsoft - ");
349 else printf(
"%lu\n", lim.rlim_cur);
354 else printf(
"%lu\n", lim.rlim_max);
362 check_coredump_limit();
371 pid = start_ptraced_child();
373 fatal(
"Failed to initialize default registers");
374 stop_ptraced_child(pid, 1, 1);
377 static int __init noprocmm_cmd_param(
char *
str,
int*
add)
385 " Turns off usage of /proc/mm, even if host supports it.\n"
386 " To support /proc/mm, the host needs to be patched using\n"
387 " the current skas3 patch.\n\n");
389 static int __init noptracefaultinfo_cmd_param(
char *
str,
int*
add)
391 disable_ptrace_faultinfo = 1;
395 __uml_setup(
"noptracefaultinfo", noptracefaultinfo_cmd_param,
396 "noptracefaultinfo\n"
397 " Turns off usage of PTRACE_FAULTINFO, even if host supports\n"
398 " it. To support PTRACE_FAULTINFO, the host needs to be patched\n"
399 " using the current skas3 patch.\n\n");
401 static int __init noptraceldt_cmd_param(
char *
str,
int*
add)
403 disable_ptrace_ldt = 1;
409 " Turns off usage of PTRACE_LDT, even if host supports it.\n"
410 " To support PTRACE_LDT, the host needs to be patched using\n"
411 " the current skas3 patch.\n\n");
413 static inline void check_skas3_ptrace_faultinfo(
void)
415 struct ptrace_faultinfo fi;
418 non_fatal(
" - PTRACE_FAULTINFO...");
419 pid = start_ptraced_child();
424 non_fatal(
"not found\n");
427 }
else if (disable_ptrace_faultinfo)
428 non_fatal(
"found but disabled on command line\n");
430 ptrace_faultinfo = 1;
431 non_fatal(
"found\n");
434 stop_ptraced_child(pid, 1, 1);
437 static inline void check_skas3_ptrace_ldt(
void)
441 unsigned char ldtbuf[40];
442 struct ptrace_ldt ldt_op = (
struct ptrace_ldt) {
445 .bytecount =
sizeof(ldtbuf)};
447 non_fatal(
" - PTRACE_LDT...");
448 pid = start_ptraced_child();
450 n = ptrace(
PTRACE_LDT, pid, 0, (
unsigned long) &ldt_op);
453 non_fatal(
"not found\n");
456 }
else if (disable_ptrace_ldt)
457 non_fatal(
"found, but use is disabled\n");
460 non_fatal(
"found\n");
463 stop_ptraced_child(pid, 1, 1);
467 static inline void check_skas3_proc_mm(
void)
469 non_fatal(
" - /proc/mm...");
470 if (
access(
"/proc/mm", W_OK) < 0)
472 else if (disable_proc_mm)
473 non_fatal(
"found but disabled on command line\n");
476 non_fatal(
"found\n");
482 non_fatal(
"Checking for the skas3 patch in the host:\n");
484 check_skas3_proc_mm();
485 check_skas3_ptrace_faultinfo();
486 check_skas3_ptrace_ldt();
488 if (!proc_mm || !ptrace_faultinfo || !ptrace_ldt)
502 fprintf(stderr,
"parse_iomem : failed to parse iomem\n");
509 perror(
"parse_iomem - Couldn't open io file");
513 if (fstat64(fd, &buf) < 0) {
514 perror(
"parse_iomem - cannot stat_fd file");
518 new =
malloc(
sizeof(*
new));
520 perror(
"Couldn't allocate iomem_region struct");
524 size = (buf.
st_size + UM_KERN_PAGE_SIZE) & ~(UM_KERN_PAGE_SIZE - 1);