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));