From 965cb60a21674edb8e20b1a2a41297bcd4622361 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sun, 11 Jan 2009 04:44:06 +0000 Subject: * sysdeps/generic/dl-osinfo.h (_dl_setup_stack_chk_guard): Take one parameter. If non-NULL use it to initialize return value. (_dl_setup_pointer_guard): New function. * sysdeps/unix/sysv/linux/dl-osinfo.h: Likewise. * sysdeps/generic/ldsodefs.h: Declare _dl_random. * elf/rtld.c (security_init): Pass _dl_random to _dl_setup_stack_chk_guard. Call _dl_setup_pointer_guard to initialize pointer_chk_guard. * elf/dl-sysdep.c (_dl_random): New variable. (_dl_sysdep_start): Handle AT_RANDOM. (_dl_show_auxv): Likewise. * elf/dl-support.c (_dl_random): New variable. (_dl_aux_init): Handle AT_RANDOM. * csu/libc-start.c [!SHARED] (libc_start_main): Pass _dl_random to _dl_setup_stack_chk_guard. * elf/elf.h (AT_RANDOM): Define AT_BASE_PLATFORM and AT_RANDOM. --- sysdeps/unix/sysv/linux/dl-osinfo.h | 56 ++++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 13 deletions(-) (limited to 'sysdeps/unix/sysv/linux/dl-osinfo.h') diff --git a/sysdeps/unix/sysv/linux/dl-osinfo.h b/sysdeps/unix/sysv/linux/dl-osinfo.h index 5271d4e4de..415002b1b2 100644 --- a/sysdeps/unix/sysv/linux/dl-osinfo.h +++ b/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-2007,2008 Free Software Foundation, Inc. + Copyright (C) 2000-2002,2004-2008, 2009 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 @@ -60,22 +60,52 @@ dl_fatal (const char *str) } while (0) static inline uintptr_t __attribute__ ((always_inline)) -_dl_setup_stack_chk_guard (void) +_dl_setup_stack_chk_guard (void *dl_random) { uintptr_t ret; -#ifdef ENABLE_STACKGUARD_RANDOMIZE - int fd = __open ("/dev/urandom", O_RDONLY); - if (fd >= 0) +#ifndef __ASSUME_AT_RANDOM + if (__builtin_expect (dl_random == NULL, 0)) { - ssize_t reslen = __read (fd, &ret, sizeof (ret)); - __close (fd); - if (reslen == (ssize_t) sizeof (ret)) - return ret; +# ifdef ENABLE_STACKGUARD_RANDOMIZE + int fd = __open ("/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; + } +# endif + ret = 0; + unsigned char *p = (unsigned char *) &ret; + p[sizeof (ret) - 1] = 255; + p[sizeof (ret) - 2] = '\n'; } + else #endif - ret = 0; - unsigned char *p = (unsigned char *) &ret; - p[sizeof (ret) - 1] = 255; - p[sizeof (ret) - 2] = '\n'; + /* 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; +} + +static inline uintptr_t __attribute__ ((always_inline)) +_dl_setup_pointer_guard (void *dl_random, uintptr_t stack_chk_guard) +{ + uintptr_t ret; +#ifndef __ASSUME_AT_RANDOM + if (dl_random == NULL) + { + ret = stack_chk_guard; +# ifndef HP_TIMING_NONAVAIL + hp_timing_t now; + HP_TIMING_NOW (now); + ret ^= now; +# endif + } + else +#endif + memcpy (&ret, (char *) dl_random + sizeof (ret), sizeof (ret)); return ret; } -- cgit 1.4.1