diff options
author | Ulrich Drepper <drepper@gmail.com> | 2011-05-15 10:59:07 -0400 |
---|---|---|
committer | Ulrich Drepper <drepper@gmail.com> | 2011-05-15 10:59:07 -0400 |
commit | 15a856b1090669df0aec536edbdf240e71a470ca (patch) | |
tree | 7c5919f3014dd5dfa37fbdfb4be12e1ae78ab921 /sysdeps/generic | |
parent | 05f399e63428b5129ca54f9edefbf2876f82b75c (diff) | |
download | glibc-15a856b1090669df0aec536edbdf240e71a470ca.tar glibc-15a856b1090669df0aec536edbdf240e71a470ca.tar.gz glibc-15a856b1090669df0aec536edbdf240e71a470ca.tar.bz2 glibc-15a856b1090669df0aec536edbdf240e71a470ca.zip |
Make stack canary value harder to read through read overflow
Diffstat (limited to 'sysdeps/generic')
-rw-r--r-- | sysdeps/generic/dl-osinfo.h | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/sysdeps/generic/dl-osinfo.h b/sysdeps/generic/dl-osinfo.h index 4b880dae34..3af064cf54 100644 --- a/sysdeps/generic/dl-osinfo.h +++ b/sysdeps/generic/dl-osinfo.h @@ -1,5 +1,5 @@ /* Operating system specific code for generic dynamic loader functions. - Copyright (C) 2009 Free Software Foundation, Inc. + Copyright (C) 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 @@ -17,23 +17,35 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include <endian.h> #include <stdint.h> 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 = { 0 }; + if (dl_random == NULL) { - ret = 0; - unsigned char *p = (unsigned char *) &ret; - p[sizeof (ret) - 1] = 255; - p[sizeof (ret) - 2] = '\n'; - p[0] = 0; + ret.bytes[sizeof (ret) - 2] = 255; + ret.bytes[sizeof (ret) - 3] = '\n'; } else - memcpy (&ret, dl_random, sizeof (ret)); - return ret; + { + 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)) |