summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorRoger A. Faulkner <Roger.Faulkner@Sun.COM>2010-01-04 18:51:17 -0800
committerRoger A. Faulkner <Roger.Faulkner@Sun.COM>2010-01-04 18:51:17 -0800
commit3de0cfbbf9e20fa62076511a2df970d72b5585e2 (patch)
treead952dfa7da8a10f8b3e51620700a9ef0c736766 /usr/src
parente2eaebfbad27744e022534ec4d60f3a56fcbbc8e (diff)
downloadillumos-joyent-3de0cfbbf9e20fa62076511a2df970d72b5585e2.tar.gz
6913469 longjmp() from a signal handler disables subsequent atfork handlers
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/lib/libc/amd64/Makefile3
-rw-r--r--usr/src/lib/libc/amd64/gen/setjmp.s21
-rw-r--r--usr/src/lib/libc/i386/Makefile.com3
-rw-r--r--usr/src/lib/libc/i386/gen/setjmp.s30
-rw-r--r--usr/src/lib/libc/i386/offsets.in10
-rw-r--r--usr/src/lib/libc/port/threads/sigaction.c15
-rw-r--r--usr/src/lib/libc/sparc/Makefile.com3
-rw-r--r--usr/src/lib/libc/sparc/gen/setjmp.s22
-rw-r--r--usr/src/lib/libc/sparc/offsets.in10
-rw-r--r--usr/src/lib/libc/sparcv9/Makefile.com3
-rw-r--r--usr/src/lib/libc/sparcv9/gen/setjmp.s20
11 files changed, 107 insertions, 33 deletions
diff --git a/usr/src/lib/libc/amd64/Makefile b/usr/src/lib/libc/amd64/Makefile
index 0bcff6db21..85527634fb 100644
--- a/usr/src/lib/libc/amd64/Makefile
+++ b/usr/src/lib/libc/amd64/Makefile
@@ -20,7 +20,7 @@
#
#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -1119,6 +1119,7 @@ ASSYMDEP_OBJS= \
_stack_grow.o \
asm_subr.o \
getcontext.o \
+ setjmp.o \
tls_get_addr.o \
vforkx.o
diff --git a/usr/src/lib/libc/amd64/gen/setjmp.s b/usr/src/lib/libc/amd64/gen/setjmp.s
index 9bba833693..2f6a3b38b3 100644
--- a/usr/src/lib/libc/amd64/gen/setjmp.s
+++ b/usr/src/lib/libc/amd64/gen/setjmp.s
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -48,6 +48,7 @@
*/
#include <sys/asm_linkage.h>
+#include <../assym.h>
ANSI_PRAGMA_WEAK(setjmp,function)
ANSI_PRAGMA_WEAK(longjmp,function)
@@ -62,6 +63,14 @@
popq %rdx /* return address */
movq %rsp, 48(%rdi)
movq %rdx, 56(%rdi)
+
+ movq %fs:UL_SIGLINK, %rax
+ xorq %rcx, %rcx
+ testq %rax, %rax /* are we in a signal handler? */
+ jnz 1f
+ incq %rcx /* no, tell longjmp to clear ul_siglink */
+1: orq %rcx, 48(%rdi) /* low-order 1-bit flag in the saved %rsp */
+
xorl %eax, %eax /* return 0 */
jmp *%rdx
SET_SIZE(setjmp)
@@ -73,7 +82,15 @@
movq 24(%rdi), %r14
movq 32(%rdi), %r15
movq 40(%rdi), %rbp
- movq 48(%rdi), %rsp
+
+ movq 48(%rdi), %rax /* test low-order bit in the saved %rsp */
+ testq $1, %rax
+ jz 1f
+ xorq %rcx, %rcx /* if set, clear ul_siglink */
+ movq %rcx, %fs:UL_SIGLINK
+ subq $1, %rax /* clear the flag bit */
+1: movq %rax, %rsp
+
movl %esi, %eax
test %eax, %eax /* if val != 0 */
jnz 1f /* return val */
diff --git a/usr/src/lib/libc/i386/Makefile.com b/usr/src/lib/libc/i386/Makefile.com
index c90b5e3e3a..b4e26c8f67 100644
--- a/usr/src/lib/libc/i386/Makefile.com
+++ b/usr/src/lib/libc/i386/Makefile.com
@@ -20,7 +20,7 @@
#
#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -1192,6 +1192,7 @@ ASSYMDEP_OBJS= \
_lwp_mutex_unlock.o \
_stack_grow.o \
getcontext.o \
+ setjmp.o \
tls_get_addr.o \
vforkx.o
diff --git a/usr/src/lib/libc/i386/gen/setjmp.s b/usr/src/lib/libc/i386/gen/setjmp.s
index db9ad85b82..4a724294c8 100644
--- a/usr/src/lib/libc/i386/gen/setjmp.s
+++ b/usr/src/lib/libc/i386/gen/setjmp.s
@@ -18,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -39,24 +40,32 @@
/ env[3] = %ebp 12 / stack frame
/ env[4] = %esp 16
/ env[5] = %eip 20
+/ env[6] = jmp flags 24
#include <sys/asm_linkage.h>
+#include <../assym.h>
ANSI_PRAGMA_WEAK(setjmp,function)
ANSI_PRAGMA_WEAK(longjmp,function)
-#include "SYS.h"
-
ENTRY(setjmp)
movl 4(%esp),%eax / jmpbuf address
movl %ebx,0(%eax) / save ebx
movl %esi,4(%eax) / save esi
movl %edi,8(%eax) / save edi
movl %ebp,12(%eax) / save caller's ebp
+
+ movl %gs:UL_SIGLINK, %ecx
+ xorl %edx, %edx
+ test %ecx, %ecx / are we in a signal handler?
+ jnz 1f
+ inc %edx / no, tell longjmp to clear ul_siglink
+1: movl %edx, 24(%eax) / set flag word
+
popl %edx / return address
movl %esp,16(%eax) / save caller's esp
- movl %edx,20(%eax)
- subl %eax,%eax / return 0
+ movl %edx,20(%eax) / save caller's return address
+ xorl %eax, %eax / return 0
pushl %edx
ret
SET_SIZE(setjmp)
@@ -69,9 +78,16 @@
movl 8(%edx),%edi / restore edi
movl 12(%edx),%ebp / restore caller's ebp
movl 16(%edx),%esp / restore caller's esp
+
+ movl 24(%edx), %ecx
+ test %ecx, %ecx / test flag word
+ jz 1f
+ xorl %ecx, %ecx / if set, clear ul_siglink
+ movl %ecx, %gs:UL_SIGLINK
+1:
test %eax,%eax / if val != 0
- jnz .ret / return val
+ jnz 1f / return val
incl %eax / else return 1
-.ret:
+1:
jmp *20(%edx) / return to caller
SET_SIZE(longjmp)
diff --git a/usr/src/lib/libc/i386/offsets.in b/usr/src/lib/libc/i386/offsets.in
index feaa96079b..7c9b59f0d5 100644
--- a/usr/src/lib/libc/i386/offsets.in
+++ b/usr/src/lib/libc/i386/offsets.in
@@ -1,13 +1,12 @@
\
-\ Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+\ Copyright 2010 Sun Microsystems, Inc. All rights reserved.
\ Use is subject to license terms.
\
\ CDDL HEADER START
\
\ The contents of this file are subject to the terms of the
-\ Common Development and Distribution License, Version 1.0 only
-\ (the "License"). You may not use this file except in compliance
-\ with the License.
+\ Common Development and Distribution License (the "License").
+\ You may not use this file except in compliance with the License.
\
\ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
\ or http://www.opensolaris.org/os/licensing.
@@ -23,8 +22,6 @@
\ CDDL HEADER END
\
-#pragma ident "%Z%%M% %I% %E% SMI"
-
\
\ offsets.in: input file to produce assym.h using the ctfstabs program
\
@@ -50,6 +47,7 @@ ulwp_t
ul_vfork
ul_schedctl
ul_schedctl_called
+ ul_siglink
ul_sigmask
stack_t
diff --git a/usr/src/lib/libc/port/threads/sigaction.c b/usr/src/lib/libc/port/threads/sigaction.c
index ccc9203ecd..4768daa7a6 100644
--- a/usr/src/lib/libc/port/threads/sigaction.c
+++ b/usr/src/lib/libc/port/threads/sigaction.c
@@ -20,12 +20,10 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "lint.h"
#include <sys/feature_tests.h>
/*
@@ -294,6 +292,17 @@ sigacthandler(int sig, siginfo_t *sip, void *uvp)
self->ul_cancel_async = self->ul_save_async;
/*
+ * If this thread has performed a longjmp() from a signal handler
+ * back to main level some time in the past, it has left the kernel
+ * thinking that it is still in the signal context. We repair this
+ * possible damage by setting ucp->uc_link to NULL if we know that
+ * we are actually executing at main level (self->ul_siglink == NULL).
+ * See the code for setjmp()/longjmp() for more details.
+ */
+ if (self->ul_siglink == NULL)
+ ucp->uc_link = NULL;
+
+ /*
* If we are not in a critical region and are
* not deferring signals, take the signal now.
*/
diff --git a/usr/src/lib/libc/sparc/Makefile.com b/usr/src/lib/libc/sparc/Makefile.com
index bda105c159..a7d66be272 100644
--- a/usr/src/lib/libc/sparc/Makefile.com
+++ b/usr/src/lib/libc/sparc/Makefile.com
@@ -20,7 +20,7 @@
#
#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -1254,6 +1254,7 @@ ASSYMDEP_OBJS= \
_lwp_mutex_unlock.o \
_stack_grow.o \
asm_subr.o \
+ setjmp.o \
tls_get_addr.o \
unwind_frame.o \
vforkx.o
diff --git a/usr/src/lib/libc/sparc/gen/setjmp.s b/usr/src/lib/libc/sparc/gen/setjmp.s
index 517f5fe82f..71a64fddff 100644
--- a/usr/src/lib/libc/sparc/gen/setjmp.s
+++ b/usr/src/lib/libc/sparc/gen/setjmp.s
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,6 +34,7 @@
ANSI_PRAGMA_WEAK(setjmp,function)
ANSI_PRAGMA_WEAK(longjmp,function)
+#include <../assym.h>
#include <sys/trap.h>
JB_FLAGS = (0*4) ! offsets in jmpbuf (see siglonglmp.c)
@@ -43,13 +44,23 @@ JB_FP = (3*4)
JB_I7 = (4*4)
/*
+ * Flag telling longjmp to set curthread->ul_siglink to NULL.
+ */
+JB_CLEARLINK = 0x10
+
+/*
* setjmp(buf_ptr)
* buf_ptr points to a twelve word array (jmp_buf)
*/
ENTRY(setjmp)
- clr [%o0 + JB_FLAGS] ! clear flags (used by sigsetjmp)
+ clr %o2
+ ld [%g7 + UL_SIGLINK], %o1 ! are we in a signal context?
+ tst %o1
+ be,a,pt %icc, 1f
+ mov JB_CLEARLINK, %o2 ! no, tell longjmp to clear ul_siglink
+1: st %o2, [%o0 + JB_FLAGS]
st %sp, [%o0 + JB_SP] ! save caller's sp
- add %o7, 8, %o1 ! comupte return pc
+ add %o7, 8, %o1 ! compute return pc
st %o1, [%o0 + JB_PC] ! save pc
st %fp, [%o0 + JB_FP] ! save fp
st %i7, [%o0 + JB_I7] ! save %i7
@@ -103,6 +114,11 @@ JB_I7 = (4*4)
ldd [%o2 + (6*8)], %i4
ld [%o0 + JB_FP], %fp ! restore fp
mov %o2, %sp ! restore sp
+ ld [%o0 + JB_FLAGS], %o2
+ btst JB_CLEARLINK, %o2 ! test JB_CLEARLINK flag
+ bne,a,pt %icc, 1f
+ clr [%g7 + UL_SIGLINK] ! if set, clear ul_siglink
+1:
ld [%o0 + JB_I7], %i7 ! restore %i7
ld [%o0 + JB_PC], %o3 ! get new return pc
tst %o1 ! is return value 0?
diff --git a/usr/src/lib/libc/sparc/offsets.in b/usr/src/lib/libc/sparc/offsets.in
index dd625da012..35a854e747 100644
--- a/usr/src/lib/libc/sparc/offsets.in
+++ b/usr/src/lib/libc/sparc/offsets.in
@@ -1,13 +1,12 @@
\
-\ Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+\ Copyright 2010 Sun Microsystems, Inc. All rights reserved.
\ Use is subject to license terms.
\
\ CDDL HEADER START
\
\ The contents of this file are subject to the terms of the
-\ Common Development and Distribution License, Version 1.0 only
-\ (the "License"). You may not use this file except in compliance
-\ with the License.
+\ Common Development and Distribution License (the "License").
+\ You may not use this file except in compliance with the License.
\
\ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
\ or http://www.opensolaris.org/os/licensing.
@@ -23,8 +22,6 @@
\ CDDL HEADER END
\
-#pragma ident "%Z%%M% %I% %E% SMI"
-
\
\ offsets.in: input file to produce assym.h using the ctfstabs program
\
@@ -50,6 +47,7 @@ ulwp_t
ul_vfork
ul_schedctl
ul_schedctl_called
+ ul_siglink
ul_sigmask
ul_unwind_ret
diff --git a/usr/src/lib/libc/sparcv9/Makefile.com b/usr/src/lib/libc/sparcv9/Makefile.com
index 3956149134..b88e9ba202 100644
--- a/usr/src/lib/libc/sparcv9/Makefile.com
+++ b/usr/src/lib/libc/sparcv9/Makefile.com
@@ -20,7 +20,7 @@
#
#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -1174,6 +1174,7 @@ ASSYMDEP_OBJS= \
_lwp_mutex_unlock.o \
_stack_grow.o \
asm_subr.o \
+ setjmp.o \
tls_get_addr.o \
unwind_frame.o \
vforkx.o
diff --git a/usr/src/lib/libc/sparcv9/gen/setjmp.s b/usr/src/lib/libc/sparcv9/gen/setjmp.s
index 0310cb6827..048aa4ec8b 100644
--- a/usr/src/lib/libc/sparcv9/gen/setjmp.s
+++ b/usr/src/lib/libc/sparcv9/gen/setjmp.s
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,6 +34,7 @@
ANSI_PRAGMA_WEAK(setjmp,function)
ANSI_PRAGMA_WEAK(longjmp,function)
+#include <../assym.h>
#include <sys/trap.h>
JB_FLAGS = (0*8) ! offsets in jmpbuf (see siglongjmp.c)
@@ -43,11 +44,21 @@ JB_FP = (3*8)
JB_I7 = (4*8)
/*
+ * Flag telling longjmp to set curthread->ul_siglink to NULL.
+ */
+JB_CLEARLINK = 0x10
+
+/*
* setjmp(buf_ptr)
* buf_ptr points to a twelve word array (jmp_buf)
*/
ENTRY(setjmp)
- clr [%o0 + JB_FLAGS] ! clear flags (used by sigsetjmp)
+ clr %o2
+ ldx [%g7 + UL_SIGLINK], %o1 ! are we in a signal context?
+ tst %o1
+ be,a,pt %xcc, 1f
+ mov JB_CLEARLINK, %o2 ! no, tell longjmp to clear ul_siglink
+1: stx %o2, [%o0 + JB_FLAGS]
stx %sp, [%o0 + JB_SP] ! save caller's sp
add %o7, 8, %o1 ! compute return pc
stx %o1, [%o0 + JB_PC] ! save pc
@@ -110,6 +121,11 @@ JB_I7 = (4*8)
ldx [%o2 + (13*8) + STACK_BIAS], %i5
ldx [%o0 + JB_FP], %fp ! restore fp
mov %o2, %sp ! restore sp
+ ldx [%o0 + JB_FLAGS], %o2
+ btst JB_CLEARLINK, %o2 ! test JB_CLEARLINK flag
+ bne,a,pt %xcc, 1f
+ clrx [%g7 + UL_SIGLINK] ! if set, clear ul_siglink
+1:
ldx [%o0 + JB_I7], %i7 ! restore %i7
ldx [%o0 + JB_PC], %o3 ! get new return pc
tst %o1 ! is return value 0?