diff options
author | Roger A. Faulkner <Roger.Faulkner@Sun.COM> | 2010-01-04 18:51:17 -0800 |
---|---|---|
committer | Roger A. Faulkner <Roger.Faulkner@Sun.COM> | 2010-01-04 18:51:17 -0800 |
commit | 3de0cfbbf9e20fa62076511a2df970d72b5585e2 (patch) | |
tree | ad952dfa7da8a10f8b3e51620700a9ef0c736766 /usr/src | |
parent | e2eaebfbad27744e022534ec4d60f3a56fcbbc8e (diff) | |
download | illumos-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/Makefile | 3 | ||||
-rw-r--r-- | usr/src/lib/libc/amd64/gen/setjmp.s | 21 | ||||
-rw-r--r-- | usr/src/lib/libc/i386/Makefile.com | 3 | ||||
-rw-r--r-- | usr/src/lib/libc/i386/gen/setjmp.s | 30 | ||||
-rw-r--r-- | usr/src/lib/libc/i386/offsets.in | 10 | ||||
-rw-r--r-- | usr/src/lib/libc/port/threads/sigaction.c | 15 | ||||
-rw-r--r-- | usr/src/lib/libc/sparc/Makefile.com | 3 | ||||
-rw-r--r-- | usr/src/lib/libc/sparc/gen/setjmp.s | 22 | ||||
-rw-r--r-- | usr/src/lib/libc/sparc/offsets.in | 10 | ||||
-rw-r--r-- | usr/src/lib/libc/sparcv9/Makefile.com | 3 | ||||
-rw-r--r-- | usr/src/lib/libc/sparcv9/gen/setjmp.s | 20 |
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? |