summaryrefslogtreecommitdiff
path: root/arch/um/os-Linux/util.c
diff options
context:
space:
mode:
authorRandy Dunlap <randy.dunlap@oracle.com>2011-05-20 09:10:04 -0700
committerRandy Dunlap <randy.dunlap@oracle.com>2011-05-20 09:10:04 -0700
commit2f3e4af471e38e0658e701973238ae4b5e50fcd6 (patch)
treefbfc99c0d975e38ff80f4ff3239a9fc0567b8a4d /arch/um/os-Linux/util.c
parent61516587513c84ac26e68e3ab008dc6e965d0378 (diff)
parentd410fa4ef99112386de5f218dd7df7b4fca910b4 (diff)
Merge branch 'docs-security' into docs-move
Diffstat (limited to 'arch/um/os-Linux/util.c')
-rw-r--r--arch/um/os-Linux/util.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c
index 6ea77979531c..42827cafa6af 100644
--- a/arch/um/os-Linux/util.c
+++ b/arch/um/os-Linux/util.c
@@ -5,6 +5,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
@@ -75,6 +76,26 @@ void setup_hostinfo(char *buf, int len)
host.release, host.version, host.machine);
}
+/*
+ * We cannot use glibc's abort(). It makes use of tgkill() which
+ * has no effect within UML's kernel threads.
+ * After that glibc would execute an invalid instruction to kill
+ * the calling process and UML crashes with SIGSEGV.
+ */
+static inline void __attribute__ ((noreturn)) uml_abort(void)
+{
+ sigset_t sig;
+
+ fflush(NULL);
+
+ if (!sigemptyset(&sig) && !sigaddset(&sig, SIGABRT))
+ sigprocmask(SIG_UNBLOCK, &sig, 0);
+
+ for (;;)
+ if (kill(getpid(), SIGABRT) < 0)
+ exit(127);
+}
+
void os_dump_core(void)
{
int pid;
@@ -116,5 +137,5 @@ void os_dump_core(void)
while ((pid = waitpid(-1, NULL, WNOHANG | __WALL)) > 0)
os_kill_ptraced_process(pid, 0);
- abort();
+ uml_abort();
}