summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2014-10-23 01:43:54 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2014-10-23 01:43:54 +0000
commit83a63e6bb2a107296e87f40eec1b49f6b6d594b9 (patch)
tree906b3a2e04405d620634963a31579c53a6033394
parentb70635ea552b62a2431065ae9f27eafa1c9801e5 (diff)
downloadillumos-joyent-83a63e6bb2a107296e87f40eec1b49f6b6d594b9.tar.gz
OS-3445 lxbrand 64bit sudo core dumps on exit
-rw-r--r--usr/src/lib/brand/lx/lx_brand/amd64/lx_handler.s10
-rw-r--r--usr/src/lib/brand/lx/lx_brand/amd64/offsets.in8
-rw-r--r--usr/src/lib/brand/lx/lx_brand/common/signal.c42
-rw-r--r--usr/src/lib/brand/lx/lx_brand/sys/lx_sigstack.h73
4 files changed, 92 insertions, 41 deletions
diff --git a/usr/src/lib/brand/lx/lx_brand/amd64/lx_handler.s b/usr/src/lib/brand/lx/lx_brand/amd64/lx_handler.s
index 45625a83f2..8e347d1245 100644
--- a/usr/src/lib/brand/lx/lx_brand/amd64/lx_handler.s
+++ b/usr/src/lib/brand/lx/lx_brand/amd64/lx_handler.s
@@ -331,13 +331,15 @@ lx_sigreturn_tolibc(uintptr_t sp)
movq -16(%rbp), %rsi
cmp $0, %rsi
je 1f
- movq 8(%rsp), %rsi
+ movq %rsp, %rsi
+ addq $SI, %rsi
1:
/*
- * arg2 %rdx is ptr to converted ucontext on stk
- * LX_SI_MAX_SIZE + sizeof (void *)
+ * arg2 %rdx is ptr to converted ucontext on stk (uc member of
+ * lx_sigstack).
*/
- movq 136(%rsp), %rdx
+ movq %rsp, %rdx
+ addq $UC, %rdx
movq -48(%rbp), %r9 /* fetch signal handler ptr */
jmp *%r9 /* jmp to the Linux signal handler */
diff --git a/usr/src/lib/brand/lx/lx_brand/amd64/offsets.in b/usr/src/lib/brand/lx/lx_brand/amd64/offsets.in
index b774986e24..207063a886 100644
--- a/usr/src/lib/brand/lx/lx_brand/amd64/offsets.in
+++ b/usr/src/lib/brand/lx/lx_brand/amd64/offsets.in
@@ -12,6 +12,7 @@
\
#include <sys/lx_brand.h>
+#include <sys/lx_sigstack.h>
lx_regs_t SIZEOF_LX_REGS_T
lxr_fs
@@ -33,3 +34,10 @@ lx_regs_t SIZEOF_LX_REGS_T
lxr_r15
lxr_rip
lxr_orig_rax
+
+lx_sigstack_t SIZEOF_LX_SIGSTACK_T
+ retaddr
+ si
+ uc
+ fpstate
+ pad
diff --git a/usr/src/lib/brand/lx/lx_brand/common/signal.c b/usr/src/lib/brand/lx/lx_brand/common/signal.c
index e59bc26c9e..0f3a7d847c 100644
--- a/usr/src/lib/brand/lx/lx_brand/common/signal.c
+++ b/usr/src/lib/brand/lx/lx_brand/common/signal.c
@@ -36,6 +36,7 @@
#include <sys/lx_misc.h>
#include <sys/lx_debug.h>
#include <sys/lx_signal.h>
+#include <sys/lx_sigstack.h>
#include <sys/lx_syscall.h>
#include <sys/lx_thread.h>
#include <sys/syscall.h>
@@ -280,42 +281,6 @@ static int lx_setcontext(const ucontext_t *ucp);
* location originally interrupted by receipt of the signal.
*/
-/*
- * Two flavors of Linux signal stacks:
- *
- * lx_sigstack - used for "modern" signal handlers, in practice those
- * that have the sigaction(2) flag SA_SIGINFO set
- *
- * lx_oldsigstack - used for legacy signal handlers, those that do not have
- * the sigaction(2) flag SA_SIGINFO set or that were setup via
- * the signal(2) call.
- *
- * NOTE: Since these structures will be placed on the stack and stack math will
- * be done with their sizes, for the 32-bit code they must be word
- * aligned in size (4 bytes) so the stack remains word aligned per the
- * i386 ABI, or, for 64-bit code they must be 16 byte aligned as per the
- * AMD64 ABI.
- */
-#if defined(_LP64)
-struct lx_sigstack {
- void (*retaddr)(); /* address of real lx_rt_sigreturn code */
- lx_siginfo_t si; /* saved signal information */
- lx_ucontext_t uc; /* saved user context */
- lx_fpstate_t fpstate; /* saved FP state */
- char pad[2]; /* stack alignment */
-};
-#else
-struct lx_sigstack {
- void (*retaddr)(); /* address of real lx_rt_sigreturn code */
- int sig; /* signal number */
- lx_siginfo_t *sip; /* points to "si" if valid, NULL if not */
- lx_ucontext_t *ucp; /* points to "uc" */
- lx_siginfo_t si; /* saved signal information */
- lx_ucontext_t uc; /* saved user context */
- lx_fpstate_t fpstate; /* saved FP state */
- char trampoline[8]; /* code for trampoline to lx_rt_sigreturn() */
-};
-#endif
struct lx_oldsigstack {
void (*retaddr)(); /* address of real lx_sigreturn code */
@@ -1438,7 +1403,10 @@ lx_build_signal_frame(int lx_sig, siginfo_t *sip, void *p, void *sp)
* This should only return an error if the signum is invalid but that
* also gets converted into a LX_SIGKILL by this function.
*/
- (void) stol_siginfo(sip, &lx_ssp->si);
+ if (sip != NULL)
+ (void) stol_siginfo(sip, &lx_ssp->si);
+ else
+ bzero(&lx_ssp->si, sizeof (lx_siginfo_t));
/* convert FP regs if present */
if (ucp->uc_flags & UC_FPU) {
diff --git a/usr/src/lib/brand/lx/lx_brand/sys/lx_sigstack.h b/usr/src/lib/brand/lx/lx_brand/sys/lx_sigstack.h
new file mode 100644
index 0000000000..219bac5f21
--- /dev/null
+++ b/usr/src/lib/brand/lx/lx_brand/sys/lx_sigstack.h
@@ -0,0 +1,73 @@
+/*
+* This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ * Copyright 2014 Joyent, Inc. All rights reserved.
+ */
+
+#ifndef _SYS_LX_SIGSTACK_H
+#define _SYS_LX_SIGSTACK_H
+
+#if !defined(_ASM)
+#include <sys/lx_types.h>
+#include <sys/ucontext.h>
+#include <sys/lx_signal.h>
+#include <lx_signum.h>
+
+#endif /* !defined(_ASM) */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Two flavors of Linux signal stacks:
+ *
+ * lx_sigstack - used for "modern" signal handlers, in practice those
+ * that have the sigaction(2) flag SA_SIGINFO set
+ *
+ * lx_oldsigstack - used for legacy signal handlers, those that do not have
+ * the sigaction(2) flag SA_SIGINFO set or that were setup via
+ * the signal(2) call.
+ *
+ * NOTE: Since these structures will be placed on the stack and stack math will
+ * be done with their sizes, for the 32-bit code they must be word
+ * aligned in size (4 bytes) so the stack remains word aligned per the
+ * i386 ABI, or, for 64-bit code they must be 16 byte aligned as per the
+ * AMD64 ABI.
+ */
+#if defined(_LP64)
+typedef struct lx_sigstack {
+ void (*retaddr)(); /* address of real lx_rt_sigreturn code */
+ lx_siginfo_t si; /* saved signal information */
+ lx_ucontext_t uc; /* saved user context */
+ lx_fpstate_t fpstate; /* saved FP state */
+ char pad[2]; /* stack alignment */
+} lx_sigstack_t;
+#else
+struct lx_sigstack {
+ void (*retaddr)(); /* address of real lx_rt_sigreturn code */
+ int sig; /* signal number */
+ lx_siginfo_t *sip; /* points to "si" if valid, NULL if not */
+ lx_ucontext_t *ucp; /* points to "uc" */
+ lx_siginfo_t si; /* saved signal information */
+ lx_ucontext_t uc; /* saved user context */
+ lx_fpstate_t fpstate; /* saved FP state */
+ char trampoline[8]; /* code for trampoline to lx_rt_sigreturn() */
+};
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_LX_SIGSTACK_H */