diff options
author | Ulrich Drepper <drepper@redhat.com> | 2007-01-17 08:37:26 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2007-01-17 08:37:26 +0000 |
commit | ea1533e08df4c63e680438ac1dc243cdc37d205a (patch) | |
tree | d7954d886b979b8bea1d7e1f6db05b440a693097 /nptl/sysdeps/unix | |
parent | d78bce1c01fe67d02d833e026e5acbb88d1d9836 (diff) | |
download | glibc-ea1533e08df4c63e680438ac1dc243cdc37d205a.tar.gz glibc-ea1533e08df4c63e680438ac1dc243cdc37d205a.tar.xz glibc-ea1533e08df4c63e680438ac1dc243cdc37d205a.zip |
* sysdeps/unix/sysv/linux/libc_pthread_init.c: Don't just copy the
function table, mangle the pointers. * sysdeps/pthread/pthread-functions.h: Define PTHFCT_CALL. * forward.c: Use PTHFCT_CALL and __libc_pthread_functions_init. * sysdeps/pthread/bits/libc-lock.h: When using __libc_pthread_functions demangle pointers before use. * sysdeps/unix/sysv/linux/s390/jmp-unwind.c: Use PTHFCT_CALL to demangle pointer. * sysdeps/unix/sysv/linux/jmp-unwind.c: Likewise. * sysdeps/pthread/setxid.h: Likewise.
Diffstat (limited to 'nptl/sysdeps/unix')
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/jmp-unwind.c | 12 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c | 35 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/s390/jmp-unwind.c | 15 |
3 files changed, 40 insertions, 22 deletions
diff --git a/nptl/sysdeps/unix/sysv/linux/jmp-unwind.c b/nptl/sysdeps/unix/sysv/linux/jmp-unwind.c index c435eff307..f2795510ab 100644 --- a/nptl/sysdeps/unix/sysv/linux/jmp-unwind.c +++ b/nptl/sysdeps/unix/sysv/linux/jmp-unwind.c @@ -1,5 +1,5 @@ /* Clean up stack frames unwound by longjmp. Linux version. - Copyright (C) 1995, 1997, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1995, 1997, 2002, 2003, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -29,11 +29,11 @@ void _longjmp_unwind (jmp_buf env, int val) { #ifdef SHARED -# define fptr __libc_pthread_functions.ptr___pthread_cleanup_upto + if (__libc_pthread_functions_init) + PTHFCT_CALL (ptr___pthread_cleanup_upto, (env->__jmpbuf, + CURRENT_STACK_FRAME)); #else -# define fptr __pthread_cleanup_upto + if (__pthread_cleanup_upto != NULL) + __pthread_cleanup_upto (env->__jmpbuf, CURRENT_STACK_FRAME); #endif - - if (fptr != NULL) - fptr (env->__jmpbuf, CURRENT_STACK_FRAME); } diff --git a/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c b/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c index 714ad49428..92a188a2f3 100644 --- a/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c +++ b/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -25,6 +25,7 @@ #include <string.h> #include <pthreadP.h> #include <bits/libc-lock.h> +#include <sysdep.h> #ifdef TLS_MULTIPLE_THREADS_IN_TCB @@ -46,11 +47,29 @@ __libc_pthread_init (ptr, reclaim, functions) __register_atfork (NULL, NULL, reclaim, NULL); #ifdef SHARED - /* We copy the content of the variable pointed to by the FUNCTIONS - parameter to one in libc.so since this means access to the array - can be done with one memory access instead of two. */ - memcpy (&__libc_pthread_functions, functions, - sizeof (__libc_pthread_functions)); + /* Copy the function pointers into an array in libc. This enables + access with just one memory reference but moreso, it prevents + hijacking the function pointers with just one pointer change. We + "encrypt" the function pointers since we cannot write-protect the + array easily enough. */ + union ptrhack + { + struct pthread_functions pf; + void *parr[1]; + } const *src; + union ptrhack *dest; +# define NPTRS (sizeof (struct pthread_functions) / sizeof (void *)) + + src = (const void *) functions; + dest = (void *) &__libc_pthread_functions; + + for (size_t cnt = 0; cnt < NPTRS; ++cnt) + { + void *p = src->parr[cnt]; + PTR_MANGLE (p); + dest->parr[cnt] = p; + } + __libc_pthread_functions_init = 1; #endif #ifndef TLS_MULTIPLE_THREADS_IN_TCB @@ -61,7 +80,7 @@ __libc_pthread_init (ptr, reclaim, functions) #ifdef SHARED libc_freeres_fn (freeres_libptread) { - if (__libc_pthread_functions.ptr_freeres != NULL) - __libc_pthread_functions.ptr_freeres (); + if (__libc_pthread_functions_init) + PTHFCT_CALL (ptr_freeres, ()); } #endif diff --git a/nptl/sysdeps/unix/sysv/linux/s390/jmp-unwind.c b/nptl/sysdeps/unix/sysv/linux/s390/jmp-unwind.c index 36886f58a4..3c18df2c4f 100644 --- a/nptl/sysdeps/unix/sysv/linux/s390/jmp-unwind.c +++ b/nptl/sysdeps/unix/sysv/linux/s390/jmp-unwind.c @@ -1,5 +1,5 @@ /* Clean up stack frames unwound by longjmp. Linux/s390 version. - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,14 +28,13 @@ extern void __pthread_cleanup_upto (__jmp_buf env, char *targetframe); void _longjmp_unwind (jmp_buf env, int val) { + unsigned char local_var; + #ifdef SHARED -# define fptr __libc_pthread_functions.ptr___pthread_cleanup_upto + if (__libc_pthread_functions_init) + PTHFCT_CALL (ptr___pthread_cleanup_upto, (env->__jmpbuf, &local_var)); #else -# define fptr __pthread_cleanup_upto + if (__pthread_cleanup_upto != NULL) + __pthread_cleanup_upto (env->__jmpbuf, &local_var); #endif - - unsigned char local_var; - - if (fptr != NULL) - fptr (env->__jmpbuf, &local_var); } |