diff options
author | joseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2011-05-18 14:30:49 +0000 |
---|---|---|
committer | joseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2011-05-18 14:30:49 +0000 |
commit | e9d94bb485578797a67a3ef6dae7ac9e3635e963 (patch) | |
tree | 04991ea2da24b7448dcdddda044c36e1ac9d5189 /libc/sysdeps/unix/sysv/linux/dl-osinfo.h | |
parent | bc5b8c65ef17547cbab9141d66798bbb3cae9c2a (diff) |
Merge changes between r13831 and r13882 from /fsf/trunk.
git-svn-id: svn://svn.eglibc.org/trunk@13883 7b3dc134-2b1b-0410-93df-9e9f96275f8d
Diffstat (limited to 'libc/sysdeps/unix/sysv/linux/dl-osinfo.h')
-rw-r--r-- | libc/sysdeps/unix/sysv/linux/dl-osinfo.h | 48 |
1 files changed, 32 insertions, 16 deletions
diff --git a/libc/sysdeps/unix/sysv/linux/dl-osinfo.h b/libc/sysdeps/unix/sysv/linux/dl-osinfo.h index df07869bc..eb7fedc07 100644 --- a/libc/sysdeps/unix/sysv/linux/dl-osinfo.h +++ b/libc/sysdeps/unix/sysv/linux/dl-osinfo.h @@ -1,5 +1,5 @@ /* Operating system specific code for generic dynamic loader functions. Linux. - Copyright (C) 2000-2002,2004-2008, 2009 Free Software Foundation, Inc. + Copyright (C) 2000-2002,2004-2009,2011 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 @@ -19,8 +19,10 @@ #include <kernel-features.h> #include <dl-sysdep.h> +#include <endian.h> #include <fcntl.h> #include <stdint.h> +#include <not-cancel.h> #ifndef MIN # define MIN(a,b) (((a)<(b))?(a):(b)) @@ -62,32 +64,46 @@ dl_fatal (const char *str) static inline uintptr_t __attribute__ ((always_inline)) _dl_setup_stack_chk_guard (void *dl_random) { - uintptr_t ret; + union + { + uintptr_t num; + unsigned char bytes[sizeof (uintptr_t)]; + } ret; + #ifndef __ASSUME_AT_RANDOM if (__builtin_expect (dl_random == NULL, 0)) { + const size_t filllen = sizeof (ret.bytes) - 1; + ret.num = 0; # ifdef ENABLE_STACKGUARD_RANDOMIZE - int fd = __open ("/dev/urandom", O_RDONLY); + int fd = open_not_cancel_2 ("/dev/urandom", O_RDONLY); if (fd >= 0) { - ssize_t reslen = __read (fd, &ret, sizeof (ret)); - __close (fd); - if (reslen == (ssize_t) sizeof (ret)) - return ret; + ssize_t reslen = read_not_cancel (fd, ret.bytes + 1, filllen); + close_not_cancel_no_status (fd); + if (reslen == (ssize_) filllen) + return ret.num; } # endif - ret = 0; - unsigned char *p = (unsigned char *) &ret; - p[sizeof (ret) - 1] = 255; - p[sizeof (ret) - 2] = '\n'; + ret.bytes[filllen - 2] = 255; + ret.bytes[filllen - 3] = '\n'; } else #endif - /* We need in the moment only 8 bytes on 32-bit platforms and 16 - bytes on 64-bit platforms. Therefore we can use the data - directly and not use the kernel-provided data to seed a PRNG. */ - memcpy (&ret, dl_random, sizeof (ret)); - return ret; + { + /* We need in the moment only 8 bytes on 32-bit platforms and 16 + bytes on 64-bit platforms. Therefore we can use the data + directly and not use the kernel-provided data to seed a PRNG. */ + memcpy (ret.bytes, dl_random, sizeof (ret)); +#if BYTE_ORDER == LITTLE_ENDIAN + ret.num &= ~0xff; +#elif BYTE_ORDER == BIG_ENDIAN + ret.num &= ~(0xff << (8 * (sizeof (ret) - 1))); +#else +# error "BYTE_ORDER unknown" +#endif + } + return ret.num; } static inline uintptr_t __attribute__ ((always_inline)) |