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: Jeff Dike <jdike@linux.intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
14c8a77e1b
commit
f1ef9167ca
1 changed files with 16 additions and 9 deletions
|
@ -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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
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;
|
||||||
|
|
Loading…
Reference in a new issue