diff options
author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2014-10-23 01:43:54 +0000 |
---|---|---|
committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2014-10-23 01:43:54 +0000 |
commit | 83a63e6bb2a107296e87f40eec1b49f6b6d594b9 (patch) | |
tree | 906b3a2e04405d620634963a31579c53a6033394 | |
parent | b70635ea552b62a2431065ae9f27eafa1c9801e5 (diff) | |
download | illumos-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.s | 10 | ||||
-rw-r--r-- | usr/src/lib/brand/lx/lx_brand/amd64/offsets.in | 8 | ||||
-rw-r--r-- | usr/src/lib/brand/lx/lx_brand/common/signal.c | 42 | ||||
-rw-r--r-- | usr/src/lib/brand/lx/lx_brand/sys/lx_sigstack.h | 73 |
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 */ |