Mercurial > illumos > illumos-gate
changeset 11970:9c3f3660b754
6936596 take_deferred_signal() dumps core on solaris10 branded zones
author | Roger A. Faulkner <Roger.Faulkner@Sun.COM> |
---|---|
date | Mon, 22 Mar 2010 10:36:28 -0700 |
parents | cdd98a239cd1 |
children | ddd5873f34a9 |
files | usr/src/lib/brand/solaris10/s10_brand/common/s10_brand.c usr/src/lib/brand/solaris10/s10_brand/common/s10_signal.c usr/src/lib/brand/solaris10/s10_brand/sys/s10_misc.h usr/src/lib/brand/solaris10/s10_brand/sys/s10_signal.h usr/src/uts/common/brand/lx/os/lx_brand.c usr/src/uts/common/brand/sn1/sn1_brand.c usr/src/uts/common/brand/solaris10/s10_brand.c usr/src/uts/common/brand/solaris10/s10_brand.h usr/src/uts/common/sys/brand.h usr/src/uts/intel/ia32/syscall/getcontext.c usr/src/uts/sparc/syscall/getcontext.c |
diffstat | 11 files changed, 129 insertions(+), 51 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/lib/brand/solaris10/s10_brand/common/s10_brand.c Mon Mar 22 08:52:18 2010 -0600 +++ b/usr/src/lib/brand/solaris10/s10_brand/common/s10_brand.c Mon Mar 22 10:36:28 2010 -0700 @@ -2105,7 +2105,7 @@ NOSYS, /* 97 */ EMULATE(s10_sigaction, 3 | RV_DEFAULT), /* 98 */ EMULATE(s10_sigpending, 2 | RV_DEFAULT), /* 99 */ - EMULATE(s10_context, 2 | RV_DEFAULT), /* 100 */ + NOSYS, /* 100 */ NOSYS, /* 101 */ NOSYS, /* 102 */ NOSYS, /* 103 */
--- a/usr/src/lib/brand/solaris10/s10_brand/common/s10_signal.c Mon Mar 22 08:52:18 2010 -0600 +++ b/usr/src/lib/brand/solaris10/s10_brand/common/s10_signal.c Mon Mar 22 10:36:28 2010 -0700 @@ -56,6 +56,14 @@ * refer to a potentially different range and to intercenpt any "illegal" * signals that might otherwise be sent to an S10 process. * + * Important exception: + * We cannot interpose on the SYS_context system call in order to deal with the + * sigset_t contained within the ucontext_t structure because the getcontext() + * part of this system call trap would then return an incorrect set of machine + * registers. See the getcontext() functions in libc to get the gory details. + * The kernel code for getcontext() and setcontext() has been made brand-aware + * in order to deal with this. + * * Simple translation is all that is required to handle most system calls, * but signal handlers also must be interposed upon so that a user signal * handler sees proper signal numbers in its arguments, any passed siginfo_t @@ -64,14 +72,16 @@ * libc adds its own signal handler to handled signals such that the * signal delivery mechanism looks like: * - * signal -> libc sigacthandler() -> user signal handler + * signal -> + * libc sigacthandler() -> + * user signal handler() * * With interposition, this will instead look like: * * signal -> - * s10_sigacthandler() -> - * libc sigacthandler() -> - * user signal handler() + * s10_sigacthandler() -> + * libc sigacthandler() -> + * user signal handler() */ /* @@ -523,39 +533,6 @@ } /* - * Interposition upon SYS_context - */ -int -s10_context(sysret_t *rval, int flag, ucontext_t *ucp) -{ - ucontext_t uc; - int err; - - if (flag == SETCONTEXT) { - if (s10_uucopy(ucp, &uc, sizeof (ucontext_t)) != 0) - return (EFAULT); - if (uc.uc_flags & UC_SIGMASK) { - if ((err = s10sigset_to_native(&uc.uc_sigmask, - &uc.uc_sigmask)) != 0) { - (void) S10_TRUSS_POINT_2(rval, SYS_context, err, - flag, ucp); - return (err); - } - } - ucp = &uc; - } - - err = __systemcall(rval, SYS_context + 1024, flag, ucp); - if (err != 0) - return (err); - - if (flag == GETCONTEXT && (ucp->uc_flags & UC_SIGMASK)) - (void) nativesigset_to_s10(&ucp->uc_sigmask, &ucp->uc_sigmask); - - return (0); -} - -/* * Interposition upon SYS_sigsendsys */ int
--- a/usr/src/lib/brand/solaris10/s10_brand/sys/s10_misc.h Mon Mar 22 08:52:18 2010 -0600 +++ b/usr/src/lib/brand/solaris10/s10_brand/sys/s10_misc.h Mon Mar 22 10:36:28 2010 -0700 @@ -233,7 +233,6 @@ */ extern int s10sigset_to_native(const sigset_t *, sigset_t *); -extern int s10_context(); extern int s10_kill(); extern int s10_lwp_create(); extern int s10_lwp_kill();
--- a/usr/src/lib/brand/solaris10/s10_brand/sys/s10_signal.h Mon Mar 22 08:52:18 2010 -0600 +++ b/usr/src/lib/brand/solaris10/s10_brand/sys/s10_signal.h Mon Mar 22 10:36:28 2010 -0700 @@ -42,13 +42,6 @@ #endif /* !_ASM */ -/* - * Configurable in native Solaris, stick with the values assigned - * by default as _SIGRTMIN and _SIGRTMAX in S10. - */ -#define S10_SIGRTMIN 41 -#define S10_SIGRTMAX 48 - #ifdef __cplusplus } #endif
--- a/usr/src/uts/common/brand/lx/os/lx_brand.c Mon Mar 22 08:52:18 2010 -0600 +++ b/usr/src/uts/common/brand/lx/os/lx_brand.c Mon Mar 22 10:36:28 2010 -0700 @@ -105,7 +105,9 @@ lx_freelwp, lx_exitlwp, lx_elfexec, - NSIG + NULL, + NULL, + NSIG, }; struct brand_mach_ops lx_mops = {
--- a/usr/src/uts/common/brand/sn1/sn1_brand.c Mon Mar 22 08:52:18 2010 -0600 +++ b/usr/src/uts/common/brand/sn1/sn1_brand.c Mon Mar 22 10:36:28 2010 -0700 @@ -76,7 +76,9 @@ sn1_freelwp, sn1_lwpexit, sn1_elfexec, - NSIG + NULL, + NULL, + NSIG, }; #ifdef sparc
--- a/usr/src/uts/common/brand/solaris10/s10_brand.c Mon Mar 22 08:52:18 2010 -0600 +++ b/usr/src/uts/common/brand/solaris10/s10_brand.c Mon Mar 22 10:36:28 2010 -0700 @@ -61,6 +61,8 @@ void s10_lwpexit(klwp_t *); int s10_elfexec(vnode_t *, execa_t *, uarg_t *, intpdata_t *, int, long *, int, caddr_t, cred_t *, int); +void s10_sigset_native_to_s10(sigset_t *); +void s10_sigset_s10_to_native(sigset_t *); /* s10 brand */ struct brand_ops s10_brops = { @@ -79,7 +81,9 @@ s10_freelwp, s10_lwpexit, s10_elfexec, - S10_NSIG + s10_sigset_native_to_s10, + s10_sigset_s10_to_native, + S10_NSIG, }; #ifdef sparc @@ -937,6 +941,77 @@ return (0); } +void +s10_sigset_native_to_s10(sigset_t *set) +{ + int nativesig; + int s10sig; + sigset_t s10set; + + /* + * Shortcut: we know the first 32 signals are the same in both + * s10 and native Solaris. Just assign the first word. + */ + s10set.__sigbits[0] = set->__sigbits[0]; + s10set.__sigbits[1] = 0; + s10set.__sigbits[2] = 0; + s10set.__sigbits[3] = 0; + + /* + * Copy the remainder of the initial set of common signals. + */ + for (nativesig = 33; nativesig < S10_SIGRTMIN; nativesig++) + if (sigismember(set, nativesig)) + sigaddset(&s10set, nativesig); + + /* + * Convert any native RT signals to their S10 values. + */ + for (nativesig = _SIGRTMIN, s10sig = S10_SIGRTMIN; + nativesig <= _SIGRTMAX && s10sig <= S10_SIGRTMAX; + nativesig++, s10sig++) { + if (sigismember(set, nativesig)) + sigaddset(&s10set, s10sig); + } + + *set = s10set; +} + +void +s10_sigset_s10_to_native(sigset_t *set) +{ + int s10sig; + int nativesig; + sigset_t nativeset; + + /* + * Shortcut: we know the first 32 signals are the same in both + * s10 and native Solaris. Just assign the first word. + */ + nativeset.__sigbits[0] = set->__sigbits[0]; + nativeset.__sigbits[1] = 0; + nativeset.__sigbits[2] = 0; + nativeset.__sigbits[3] = 0; + + /* + * Copy the remainder of the initial set of common signals. + */ + for (s10sig = 33; s10sig < S10_SIGRTMIN; s10sig++) + if (sigismember(set, s10sig)) + sigaddset(&nativeset, s10sig); + + /* + * Convert any S10 RT signals to their native values. + */ + for (s10sig = S10_SIGRTMIN, nativesig = _SIGRTMIN; + s10sig <= S10_SIGRTMAX && nativesig <= _SIGRTMAX; + s10sig++, nativesig++) { + if (sigismember(set, s10sig)) + sigaddset(&nativeset, nativesig); + } + + *set = nativeset; +} int _init(void) @@ -978,7 +1053,6 @@ s10_emulation_table[SYS_sigsuspend] = 1; /* 96 */ s10_emulation_table[SYS_sigaction] = 1; /* 98 */ s10_emulation_table[SYS_sigpending] = 1; /* 99 */ - s10_emulation_table[SYS_context] = 1; /* 100 */ s10_emulation_table[SYS_waitid] = 1; /* 107 */ s10_emulation_table[SYS_sigsendsys] = 1; /* 108 */ #if defined(__x86)
--- a/usr/src/uts/common/brand/solaris10/s10_brand.h Mon Mar 22 08:52:18 2010 -0600 +++ b/usr/src/uts/common/brand/solaris10/s10_brand.h Mon Mar 22 10:36:28 2010 -0700 @@ -58,8 +58,11 @@ #endif /* !_LP64 */ /* - * Solaris 10 value of NSIG + * Solaris 10 value of _SIGRTMIN, _SIGRTMAX, MAXSIG, NSIG */ +#define S10_SIGRTMIN 41 +#define S10_SIGRTMAX 48 +#define S10_MAXSIG 48 #define S10_NSIG 49 /*
--- a/usr/src/uts/common/sys/brand.h Mon Mar 22 08:52:18 2010 -0600 +++ b/usr/src/uts/common/sys/brand.h Mon Mar 22 10:36:28 2010 -0700 @@ -96,6 +96,8 @@ struct uarg *args, struct intpdata *idata, int level, long *execsz, int setid, caddr_t exec_file, struct cred *cred, int brand_action); + void (*b_sigset_native_to_brand)(sigset_t *); + void (*b_sigset_brand_to_native)(sigset_t *); int b_nsig; }; @@ -121,6 +123,14 @@ #define BROP(p) ((p)->p_brand->b_ops) #define ZBROP(z) ((z)->zone_brand->b_ops) #define BRMOP(p) ((p)->p_brand->b_machops) +#define SIGSET_NATIVE_TO_BRAND(sigset) \ + if (PROC_IS_BRANDED(curproc) && \ + BROP(curproc)->b_sigset_native_to_brand) \ + BROP(curproc)->b_sigset_native_to_brand(sigset) +#define SIGSET_BRAND_TO_NATIVE(sigset) \ + if (PROC_IS_BRANDED(curproc) && \ + BROP(curproc)->b_sigset_brand_to_native) \ + BROP(curproc)->b_sigset_brand_to_native(sigset) extern void brand_init(); extern int brand_register(brand_t *);
--- a/usr/src/uts/intel/ia32/syscall/getcontext.c Mon Mar 22 08:52:18 2010 -0600 +++ b/usr/src/uts/intel/ia32/syscall/getcontext.c Mon Mar 22 10:36:28 2010 -0700 @@ -37,6 +37,7 @@ #include <sys/privregs.h> #include <sys/frame.h> #include <sys/proc.h> +#include <sys/brand.h> #include <sys/psw.h> #include <sys/ucontext.h> #include <sys/asm_linkage.h> @@ -199,6 +200,8 @@ case GETCONTEXT: schedctl_finish_sigblock(curthread); savecontext(&uc, &curthread->t_hold); + if (uc.uc_flags & UC_SIGMASK) + SIGSET_NATIVE_TO_BRAND(&uc.uc_sigmask); if (copyout(&uc, arg, sizeof (uc))) return (set_errno(EFAULT)); return (0); @@ -216,6 +219,8 @@ sizeof (uc.uc_mcontext.fpregs))) { return (set_errno(EFAULT)); } + if (uc.uc_flags & UC_SIGMASK) + SIGSET_BRAND_TO_NATIVE(&uc.uc_sigmask); if ((uc.uc_flags & UC_FPU) && copyin(&ucp->uc_mcontext.fpregs, &uc.uc_mcontext.fpregs, @@ -326,6 +331,8 @@ case GETCONTEXT: schedctl_finish_sigblock(curthread); savecontext32(&uc, &curthread->t_hold); + if (uc.uc_flags & UC_SIGMASK) + SIGSET_NATIVE_TO_BRAND(&uc.uc_sigmask); if (copyout(&uc, arg, sizeof (uc))) return (set_errno(EFAULT)); return (0); @@ -339,6 +346,8 @@ sizeof (uc.uc_mcontext.fpregs))) { return (set_errno(EFAULT)); } + if (uc.uc_flags & UC_SIGMASK) + SIGSET_BRAND_TO_NATIVE(&uc.uc_sigmask); if ((uc.uc_flags & UC_FPU) && copyin(&ucp->uc_mcontext.fpregs, &uc.uc_mcontext.fpregs, sizeof (uc.uc_mcontext.fpregs))) {
--- a/usr/src/uts/sparc/syscall/getcontext.c Mon Mar 22 08:52:18 2010 -0600 +++ b/usr/src/uts/sparc/syscall/getcontext.c Mon Mar 22 10:36:28 2010 -0700 @@ -35,6 +35,7 @@ #include <sys/stack.h> #include <sys/frame.h> #include <sys/proc.h> +#include <sys/brand.h> #include <sys/ucontext.h> #include <sys/asm_linkage.h> #include <sys/kmem.h> @@ -200,6 +201,8 @@ case GETCONTEXT: schedctl_finish_sigblock(curthread); savecontext(&uc, &curthread->t_hold); + if (uc.uc_flags & UC_SIGMASK) + SIGSET_NATIVE_TO_BRAND(&uc.uc_sigmask); /* * When using floating point it should not be possible to * get here with a fpu_qcnt other than zero since we go @@ -233,6 +236,8 @@ sizeof (uc.uc_mcontext.filler))) { return (set_errno(EFAULT)); } + if (uc.uc_flags & UC_SIGMASK) + SIGSET_BRAND_TO_NATIVE(&uc.uc_sigmask); if (copyin(&ucp->uc_mcontext.xrs, &uc.uc_mcontext.xrs, sizeof (uc.uc_mcontext.xrs))) { return (set_errno(EFAULT)); @@ -446,6 +451,8 @@ case GETCONTEXT: schedctl_finish_sigblock(curthread); savecontext32(&uc, &curthread->t_hold, NULL); + if (uc.uc_flags & UC_SIGMASK) + SIGSET_NATIVE_TO_BRAND(&uc.uc_sigmask); /* * When using floating point it should not be possible to * get here with a fpu_qcnt other than zero since we go @@ -477,6 +484,8 @@ sizeof (uc.uc_mcontext.filler))) { return (set_errno(EFAULT)); } + if (uc.uc_flags & UC_SIGMASK) + SIGSET_BRAND_TO_NATIVE(&uc.uc_sigmask); if (copyin(&ucp->uc_mcontext.xrs, &uc.uc_mcontext.xrs, sizeof (uc.uc_mcontext.xrs))) { return (set_errno(EFAULT));