Commit f1ef9167 authored by Jeff Dike's avatar Jeff Dike Committed by Linus Torvalds

uml: work around broken host PTRACE_SYSEMU

Fedora broke PTRACE_SYSEMU again, and UML crashes as a result when it
doesn't need to.  This patch makes the PTRACE_SYSEMU check fail gracefully
and makes UML fall back to PTRACE_SYSCALL.
Signed-off-by: default avatarJeff Dike <jdike@linux.intel.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 14c8a77e
...@@ -121,8 +121,10 @@ static int stop_ptraced_child(int pid, int exitcode, int mustexit) ...@@ -121,8 +121,10 @@ static int stop_ptraced_child(int pid, int exitcode, int mustexit)
{ {
int status, n, ret = 0; int status, n, ret = 0;
if (ptrace(PTRACE_CONT, pid, 0, 0) < 0) if (ptrace(PTRACE_CONT, pid, 0, 0) < 0) {
fatal_perror("stop_ptraced_child : ptrace failed"); perror("stop_ptraced_child : ptrace failed");
return -1;
}
CATCH_EINTR(n = waitpid(pid, &status, 0)); CATCH_EINTR(n = waitpid(pid, &status, 0));
if (!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { if (!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) {
int exit_with = WEXITSTATUS(status); int exit_with = WEXITSTATUS(status);
...@@ -212,7 +214,7 @@ static void __init check_sysemu(void) ...@@ -212,7 +214,7 @@ static void __init check_sysemu(void)
if (n < 0) if (n < 0)
fatal_perror("check_sysemu : wait failed"); fatal_perror("check_sysemu : wait failed");
if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
fatal("check_sysemu : expected SIGTRAP, got status = %d", fatal("check_sysemu : expected SIGTRAP, got status = %d\n",
status); status);
if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
...@@ -254,9 +256,11 @@ static void __init check_sysemu(void) ...@@ -254,9 +256,11 @@ static void __init check_sysemu(void)
if (WIFSTOPPED(status) && if (WIFSTOPPED(status) &&
(WSTOPSIG(status) == (SIGTRAP|0x80))) { (WSTOPSIG(status) == (SIGTRAP|0x80))) {
if (!count) if (!count) {
fatal("check_ptrace : SYSEMU_SINGLESTEP " non_fatal("check_ptrace : SYSEMU_SINGLESTEP "
"doesn't singlestep"); "doesn't singlestep");
goto fail;
}
n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET,
os_getpid()); os_getpid());
if (n < 0) if (n < 0)
...@@ -266,9 +270,12 @@ static void __init check_sysemu(void) ...@@ -266,9 +270,12 @@ static void __init check_sysemu(void)
} }
else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP)) else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP))
count++; count++;
else else {
fatal("check_ptrace : expected SIGTRAP or " non_fatal("check_ptrace : expected SIGTRAP or "
"(SIGTRAP | 0x80), got status = %d", status); "(SIGTRAP | 0x80), got status = %d\n",
status);
goto fail;
}
} }
if (stop_ptraced_child(pid, 0, 0) < 0) if (stop_ptraced_child(pid, 0, 0) < 0)
goto fail_stopped; goto fail_stopped;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment