Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 47486
b: refs/heads/master
c: 3a150e1
h: refs/heads/master
v: v3
  • Loading branch information
Jeff Dike authored and Linus Torvalds committed Feb 11, 2007
1 parent 11a5ca2 commit e44806d
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 63 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9683da91e2db323ee728041576e29ad7fa9547b9
refs/heads/master: 3a150e1da8bc4e840d5a09fc089052011b5b6503
154 changes: 92 additions & 62 deletions trunk/arch/um/os-Linux/start_up.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,34 @@ static int ptrace_child(void *arg)
_exit(ret);
}

static void fatal_perror(char *str)
{
perror(str);
exit(1);
}

static void fatal(char *fmt, ...)
{
va_list list;

va_start(list, fmt);
vprintf(fmt, list);
va_end(list);
fflush(stdout);

exit(1);
}

static void non_fatal(char *fmt, ...)
{
va_list list;

va_start(list, fmt);
vprintf(fmt, list);
va_end(list);
fflush(stdout);
}

static int start_ptraced_child(void **stack_out)
{
void *stack;
Expand All @@ -82,16 +110,16 @@ static int start_ptraced_child(void **stack_out)
stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if(stack == MAP_FAILED)
panic("check_ptrace : mmap failed, errno = %d", errno);
fatal_perror("check_ptrace : mmap failed");
sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
if(pid < 0)
panic("start_ptraced_child : clone failed, errno = %d", errno);
fatal_perror("start_ptraced_child : clone failed");
CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
if(n < 0)
panic("check_ptrace : clone failed, errno = %d", errno);
fatal_perror("check_ptrace : clone failed");
if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
panic("check_ptrace : expected SIGSTOP, got status = %d",
fatal("check_ptrace : expected SIGSTOP, got status = %d",
status);

*stack_out = stack;
Expand All @@ -105,31 +133,30 @@ static int start_ptraced_child(void **stack_out)
* must work anyway!
*/
static int stop_ptraced_child(int pid, void *stack, int exitcode,
int mustpanic)
int mustexit)
{
int status, n, ret = 0;

if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
panic("check_ptrace : ptrace failed, errno = %d", errno);
fatal_perror("stop_ptraced_child : ptrace failed");
CATCH_EINTR(n = waitpid(pid, &status, 0));
if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) {
int exit_with = WEXITSTATUS(status);
if (exit_with == 2)
printf("check_ptrace : child exited with status 2. "
"Serious trouble happening! Try updating your "
"host skas patch!\nDisabling SYSEMU support.");
printf("check_ptrace : child exited with exitcode %d, while "
"expecting %d; status 0x%x", exit_with,
exitcode, status);
if (mustpanic)
panic("\n");
else
printf("\n");
non_fatal("check_ptrace : child exited with status 2. "
"Serious trouble happening! Try updating "
"your host skas patch!\nDisabling SYSEMU "
"support.");
non_fatal("check_ptrace : child exited with exitcode %d, while "
"expecting %d; status 0x%x\n", exit_with,
exitcode, status);
if (mustexit)
exit(1);
ret = -1;
}

if(munmap(stack, PAGE_SIZE) < 0)
panic("check_ptrace : munmap failed, errno = %d", errno);
fatal_perror("check_ptrace : munmap failed");
return ret;
}

Expand Down Expand Up @@ -184,7 +211,7 @@ static void __init check_sysemu(void)
void *stack;
int pid, n, status, count=0;

printf("Checking syscall emulation patch for ptrace...");
non_fatal("Checking syscall emulation patch for ptrace...");
sysemu_supported = 0;
pid = start_ptraced_child(&stack);

Expand All @@ -193,61 +220,61 @@ static void __init check_sysemu(void)

CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
if (n < 0)
panic("check_sysemu : wait failed, errno = %d", errno);
fatal_perror("check_sysemu : wait failed");
if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
panic("check_sysemu : expected SIGTRAP, "
"got status = %d", status);
fatal("check_sysemu : expected SIGTRAP, got status = %d",
status);

n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET,
os_getpid());
if(n < 0)
panic("check_sysemu : failed to modify system "
"call return, errno = %d", errno);
fatal_perror("check_sysemu : failed to modify system call "
"return");

if (stop_ptraced_child(pid, stack, 0, 0) < 0)
goto fail_stopped;

sysemu_supported = 1;
printf("OK\n");
non_fatal("OK\n");
set_using_sysemu(!force_sysemu_disabled);

printf("Checking advanced syscall emulation patch for ptrace...");
non_fatal("Checking advanced syscall emulation patch for ptrace...");
pid = start_ptraced_child(&stack);

if(ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
(void *) PTRACE_O_TRACESYSGOOD) < 0)
panic("check_ptrace: PTRACE_OLDSETOPTIONS failed, errno = %d",
errno);
if((ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
(void *) PTRACE_O_TRACESYSGOOD) < 0))
fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed");

while(1){
count++;
if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0)
goto fail;
CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
if(n < 0)
panic("check_ptrace : wait failed, errno = %d", errno);
fatal_perror("check_ptrace : wait failed");

if(WIFSTOPPED(status) && (WSTOPSIG(status) == (SIGTRAP|0x80))){
if (!count)
panic("check_ptrace : SYSEMU_SINGLESTEP "
fatal("check_ptrace : SYSEMU_SINGLESTEP "
"doesn't singlestep");
n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET,
os_getpid());
if(n < 0)
panic("check_sysemu : failed to modify system "
"call return, errno = %d", errno);
fatal_perror("check_sysemu : failed to modify "
"system call return");
break;
}
else if(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP))
count++;
else
panic("check_ptrace : expected SIGTRAP or "
"(SIGTRAP|0x80), got status = %d", status);
fatal("check_ptrace : expected SIGTRAP or "
"(SIGTRAP | 0x80), got status = %d", status);
}
if (stop_ptraced_child(pid, stack, 0, 0) < 0)
goto fail_stopped;

sysemu_supported = 2;
printf("OK\n");
non_fatal("OK\n");

if ( !force_sysemu_disabled )
set_using_sysemu(sysemu_supported);
Expand All @@ -256,44 +283,47 @@ static void __init check_sysemu(void)
fail:
stop_ptraced_child(pid, stack, 1, 0);
fail_stopped:
printf("missing\n");
non_fatal("missing\n");
}

static void __init check_ptrace(void)
{
void *stack;
int pid, syscall, n, status;

printf("Checking that ptrace can change system call numbers...");
non_fatal("Checking that ptrace can change system call numbers...");
pid = start_ptraced_child(&stack);

if(ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
panic("check_ptrace: PTRACE_OLDSETOPTIONS failed, errno = %d", errno);
if((ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
(void *) PTRACE_O_TRACESYSGOOD) < 0))
fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed");

while(1){
if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
panic("check_ptrace : ptrace failed, errno = %d",
errno);
fatal_perror("check_ptrace : ptrace failed");

CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
if(n < 0)
panic("check_ptrace : wait failed, errno = %d", errno);
if(!WIFSTOPPED(status) || (WSTOPSIG(status) != (SIGTRAP|0x80)))
panic("check_ptrace : expected (SIGTRAP|0x80), "
"got status = %d", status);
fatal_perror("check_ptrace : wait failed");

if(!WIFSTOPPED(status) ||
(WSTOPSIG(status) != (SIGTRAP | 0x80)))
fatal("check_ptrace : expected (SIGTRAP|0x80), "
"got status = %d", status);

syscall = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_NR_OFFSET,
0);
if(syscall == __NR_getpid){
n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET,
__NR_getppid);
if(n < 0)
panic("check_ptrace : failed to modify system "
"call, errno = %d", errno);
fatal_perror("check_ptrace : failed to modify "
"system call");
break;
}
}
stop_ptraced_child(pid, stack, 0, 1);
printf("OK\n");
non_fatal("OK\n");
check_sysemu();
}

Expand Down Expand Up @@ -352,22 +382,22 @@ static inline void check_skas3_ptrace_faultinfo(void)
void *stack;
int pid, n;

printf(" - PTRACE_FAULTINFO...");
non_fatal(" - PTRACE_FAULTINFO...");
pid = start_ptraced_child(&stack);

n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
if (n < 0) {
ptrace_faultinfo = 0;
if(errno == EIO)
printf("not found\n");
non_fatal("not found\n");
else
perror("not found");
}
else {
if (!ptrace_faultinfo)
printf("found but disabled on command line\n");
non_fatal("found but disabled on command line\n");
else
printf("found\n");
non_fatal("found\n");
}

init_registers(pid);
Expand All @@ -385,23 +415,23 @@ static inline void check_skas3_ptrace_ldt(void)
.ptr = ldtbuf,
.bytecount = sizeof(ldtbuf)};

printf(" - PTRACE_LDT...");
non_fatal(" - PTRACE_LDT...");
pid = start_ptraced_child(&stack);

n = ptrace(PTRACE_LDT, pid, 0, (unsigned long) &ldt_op);
if (n < 0) {
if(errno == EIO)
printf("not found\n");
non_fatal("not found\n");
else {
perror("not found");
}
ptrace_ldt = 0;
}
else {
if(ptrace_ldt)
printf("found\n");
non_fatal("found\n");
else
printf("found, but use is disabled\n");
non_fatal("found, but use is disabled\n");
}

stop_ptraced_child(pid, stack, 1, 1);
Expand All @@ -416,22 +446,22 @@ static inline void check_skas3_ptrace_ldt(void)

static inline void check_skas3_proc_mm(void)
{
printf(" - /proc/mm...");
non_fatal(" - /proc/mm...");
if (access("/proc/mm", W_OK) < 0) {
proc_mm = 0;
printf("not found\n");
perror("not found");
}
else {
if (!proc_mm)
printf("found but disabled on command line\n");
non_fatal("found but disabled on command line\n");
else
printf("found\n");
non_fatal("found\n");
}
}

int can_do_skas(void)
{
printf("Checking for the skas3 patch in the host:\n");
non_fatal("Checking for the skas3 patch in the host:\n");

check_skas3_proc_mm();
check_skas3_ptrace_faultinfo();
Expand Down

0 comments on commit e44806d

Please sign in to comment.