This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch fw/heap-protector created. glibc-2.24-313-g9b685f9


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, fw/heap-protector has been created
        at  9b685f96f4a725ce996aeab7d4b7d665f1c75eeb (commit)

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=9b685f96f4a725ce996aeab7d4b7d665f1c75eeb

commit 9b685f96f4a725ce996aeab7d4b7d665f1c75eeb
Author: Florian Weimer <fweimer@redhat.com>
Date:   Fri Oct 28 11:36:12 2016 +0200

    malloc: Implement heap protector

diff --git a/ChangeLog b/ChangeLog
index 0068b47..d4322ad 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+2016-10-27  Florian Weimer  <fweimer@redhat.com>
+
+	* malloc/mallc-internal.h (__malloc_header_guard)
+	(__malloc_footer_guard): Declare.
+	* malloc/malloc-guard.c: New file.
+	* malloc/Makefile (routines): Add it.
+	* malloc/malloc.c (HEAP_CRYPT_SIZE, HEAP_CRYPT_PREVSIZE): Define.
+	(chunksize_nomask, prev_size, set_prev_size, set_head_size)
+	(set_head, set_foot): Add encryption.
+	* malloc/arena.c (ptmalloc_init): For shared builds, initialize
+	the heap guard variables.  Initialize the top chunk.
+	* malloc/hooks.c (malloc_set_state): Apply the heap guard to the
+	dumped heap.
+	* malloc/tst-mallocstate.c (malloc_usable_size_valid): New
+	variable.
+	(check_allocation): Check malloc_usable_size result if
+	malloc_usable_size_valid.
+	(init_heap): Set malloc_usable_size_valid.
+	* csu/libc-start.c (LIBC_START_MAIN): Initialize heap guard
+	variables.
+	* sysdeps/generic/ldsodefs.h (struct rtld_global_ro): Add members
+	_dl_malloc_header_guard, _dl_malloc_footer_guard.
+	* elf/rtld.c (security_init): Initialize temporary copy of the
+	heap guard variables.
+
 2016-10-28  Florian Weimer  <fweimer@redhat.com>
 
 	* elf/dl-keysetup.h: New file.
diff --git a/csu/libc-start.c b/csu/libc-start.c
index 333a4cc..ae6abde 100644
--- a/csu/libc-start.c
+++ b/csu/libc-start.c
@@ -22,6 +22,7 @@
 #include <ldsodefs.h>
 #include <exit-thread.h>
 #include <elf/dl-keysetup.h>
+#include <malloc/malloc-internal.h>
 
 extern void __libc_init_first (int argc, char **argv, char **envp);
 
@@ -210,6 +211,11 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
   __pointer_chk_guard_local = keys.pointer;
 # endif
 
+  /* In the non-shared case, we initialize the heap guard
+     directly.  */
+  __malloc_header_guard = keys.heap_header;
+  __malloc_footer_guard = keys.heap_footer;
+
 #endif
 
   /* Register the destructor of the dynamic linker if there is any.  */
diff --git a/elf/rtld.c b/elf/rtld.c
index de965da..7ea06e4 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -42,6 +42,7 @@
 #include <stap-probe.h>
 #include <stackinfo.h>
 #include <dl-keysetup.h>
+#include <malloc/malloc-internal.h>
 
 #include <assert.h>
 
@@ -716,6 +717,11 @@ security_init (void)
 #endif
   __pointer_chk_guard_local = keys.pointer;
 
+  /* Keep a copy of the computed keys, so that they can be obtained
+     during malloc initialization in libc.so.  */
+  GLRO (dl_malloc_header_guard) = keys.heap_header;
+  GLRO (dl_malloc_footer_guard) = keys.heap_footer;
+
   /* We do not need the _dl_random value anymore.  The less
      information we leave behind, the better, so clear the
      variable.  */
diff --git a/malloc/Makefile b/malloc/Makefile
index b8efcd6..cd289f8 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -41,7 +41,7 @@ tests-static := \
 tests += $(tests-static)
 test-srcs = tst-mtrace
 
-routines = malloc morecore mcheck mtrace obstack \
+routines = malloc morecore mcheck mtrace obstack malloc-guard \
   scratch_buffer_grow scratch_buffer_grow_preserve \
   scratch_buffer_set_array_size
 
diff --git a/malloc/arena.c b/malloc/arena.c
index eed4247..ada79f6 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -340,6 +340,19 @@ ptmalloc_init (void)
       if (check_action != 0)
         __malloc_check_init ();
     }
+
+#ifdef SHARED
+  /* For a shared library, elf/rtld.c performed key setup in
+     security_init, and we copy the keys.  In static builds, the guard
+     cookies have already been initialized in csu/libc-start.c.  */
+  __malloc_header_guard = GLRO (dl_malloc_header_guard);
+  __malloc_footer_guard = GLRO (dl_malloc_footer_guard);
+#endif
+
+  /* Initialize the top chunk, based on the heap protector guards.  */
+  malloc_init_state (&main_arena);
+  set_head (main_arena.top, 0);
+
 #if HAVE_MALLOC_INIT_HOOK
   void (*hook) (void) = atomic_forced_read (__malloc_initialize_hook);
   if (hook != NULL)
diff --git a/malloc/hooks.c b/malloc/hooks.c
index 12995d3..8bb2b74 100644
--- a/malloc/hooks.c
+++ b/malloc/hooks.c
@@ -537,35 +537,38 @@ malloc_set_state (void *msptr)
      dumped_main_arena_end, realloc and free will recognize these
      chunks as dumped fake mmapped chunks and never free them.  */
 
-  /* Find the chunk with the lowest address with the heap.  */
-  mchunkptr chunk = NULL;
+  /* Find the chunk with the lowest address with the heap.  If
+     successful, size_header will point to the mchunk_size member (not
+     the chunk start, i.e. the mchunck_prev_size member).  */
+  size_t *size_header = NULL;
   {
     size_t *candidate = (size_t *) ms->sbrk_base;
     size_t *end = (size_t *) (ms->sbrk_base + ms->sbrked_mem_bytes);
     while (candidate < end)
       if (*candidate != 0)
 	{
-	  chunk = mem2chunk ((void *) (candidate + 1));
+	  size_header = candidate;
 	  break;
 	}
       else
 	++candidate;
   }
-  if (chunk == NULL)
+  if (size_header == NULL)
     return 0;
 
   /* Iterate over the dumped heap and patch the chunks so that they
-     are treated as fake mmapped chunks.  */
+     are treated as fake mmapped chunks.  We cannot use the regular
+     accessors because the chunks we read are not yet encrypted.  */
   mchunkptr top = ms->av[2];
-  while (chunk < top)
+  size_t *top_size_header = ((size_t *) top) + 1;
+  while (size_header < top_size_header)
     {
-      if (inuse (chunk))
-	{
-	  /* Mark chunk as mmapped, to trigger the fallback path.  */
-	  size_t size = chunksize (chunk);
-	  set_head (chunk, size | IS_MMAPPED);
-	}
-      chunk = next_chunk (chunk);
+      size_t size = *size_header & ~SIZE_BITS;
+      /* We treat all chunks as allocated.  The heap consistency
+	 checks do not trigger because they are not active for the
+	 dumped heap.  */
+      *size_header = HEAP_CRYPT_SIZE (size) | IS_MMAPPED;
+      size_header += size / sizeof (*size_header);
     }
 
   /* The dumped fake mmapped chunks all lie in this address range.  */
diff --git a/malloc/malloc-guard.c b/malloc/malloc-guard.c
new file mode 100644
index 0000000..c8b3581
--- /dev/null
+++ b/malloc/malloc-guard.c
@@ -0,0 +1,29 @@
+/* Heap protector variables.
+   Copyright (C) 2016 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
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+/* These variables are defined in a separate file because the static
+   startup code initializes them, but this should not pull the rest of
+   the libc malloc implementation into the link.  */
+
+#include <malloc-internal.h>
+
+/* The heap cookie.  The lowest three bits (corresponding to
+   SIZE_BITS) in __malloc_guard_header must be clear.  Initialized
+   during libc startup, and computed by elf/dl-keysetup.c.  */
+INTERNAL_SIZE_T __malloc_header_guard; /* For size.  */
+INTERNAL_SIZE_T __malloc_footer_guard; /* For prev_size.  */
diff --git a/malloc/malloc-internal.h b/malloc/malloc-internal.h
index a3df8c3..e723539 100644
--- a/malloc/malloc-internal.h
+++ b/malloc/malloc-internal.h
@@ -81,5 +81,8 @@ void __malloc_fork_unlock_parent (void) internal_function attribute_hidden;
 /* Called in the child process after a fork.  */
 void __malloc_fork_unlock_child (void) internal_function attribute_hidden;
 
+/* Random values for the heap protector.  */
+extern INTERNAL_SIZE_T __malloc_header_guard attribute_hidden;
+extern INTERNAL_SIZE_T __malloc_footer_guard attribute_hidden;
 
 #endif /* _MALLOC_INTERNAL_H */
diff --git a/malloc/malloc.c b/malloc/malloc.c
index a10477e..6e586eb 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -1221,6 +1221,10 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 /* Mark a chunk as not being on the main arena.  */
 #define set_non_main_arena(p) ((p)->mchunk_size |= NON_MAIN_ARENA)
 
+/* Decrypt a heap header chunk.  */
+#define HEAP_CRYPT_SIZE(val) (__malloc_header_guard ^ ((INTERNAL_SIZE_T) val))
+#define HEAP_CRYPT_PREVSIZE(val) \
+  (__malloc_footer_guard ^ ((INTERNAL_SIZE_T) val))
 
 /*
    Bits to mask off when extracting size
@@ -1236,16 +1240,16 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 #define chunksize(p) (chunksize_nomask (p) & ~(SIZE_BITS))
 
 /* Like chunksize, but do not mask SIZE_BITS.  */
-#define chunksize_nomask(p)         ((p)->mchunk_size)
+#define chunksize_nomask(p) HEAP_CRYPT_SIZE ((p)->mchunk_size)
 
 /* Ptr to next physical malloc_chunk. */
 #define next_chunk(p) ((mchunkptr) (((char *) (p)) + chunksize (p)))
 
 /* Size of the chunk below P.  Only valid if prev_inuse (P).  */
-#define prev_size(p) ((p)->mchunk_prev_size)
+#define prev_size(p) HEAP_CRYPT_PREVSIZE ((p)->mchunk_prev_size)
 
 /* Set the size of the chunk below P.  Only valid if prev_inuse (P).  */
-#define set_prev_size(p, sz) ((p)->mchunk_prev_size = (sz))
+#define set_prev_size(p, sz) ((p)->mchunk_prev_size = HEAP_CRYPT_PREVSIZE (sz))
 
 /* Ptr to previous physical malloc_chunk.  Only valid if prev_inuse (P).  */
 #define prev_chunk(p) ((mchunkptr) (((char *) (p)) - prev_size (p)))
@@ -1277,13 +1281,16 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 
 /* Set size at head, without disturbing its use bit */
-#define set_head_size(p, s)  ((p)->mchunk_size = (((p)->mchunk_size & SIZE_BITS) | (s)))
+#define set_head_size(p, s) \
+  ((p)->mchunk_size = ((p)->mchunk_size & SIZE_BITS) | HEAP_CRYPT_SIZE (s))
 
 /* Set size/use field */
-#define set_head(p, s)       ((p)->mchunk_size = (s))
+#define set_head(p, s) ((p)->mchunk_size = HEAP_CRYPT_SIZE (s))
 
 /* Set size at footer (only when chunk is not in use) */
-#define set_foot(p, s)       (((mchunkptr) ((char *) (p) + (s)))->mchunk_prev_size = (s))
+#define set_foot(p, s) \
+  (((mchunkptr) ((char *) (p) + (s)))->mchunk_prev_size \
+    = HEAP_CRYPT_PREVSIZE (s))
 
 
 #pragma GCC poison mchunk_size
diff --git a/malloc/tst-mallocstate.c b/malloc/tst-mallocstate.c
index 7e081c5..bd6678e 100644
--- a/malloc/tst-mallocstate.c
+++ b/malloc/tst-mallocstate.c
@@ -186,6 +186,10 @@ struct allocation
   unsigned int seed;
 };
 
+/* After heap initialization, we can call malloc_usable_size to check
+   if it gives valid results.  */
+static bool malloc_usable_size_valid;
+
 /* Check that the allocation task allocation has the expected
    contents.  */
 static void
@@ -221,6 +225,23 @@ check_allocation (const struct allocation *alloc, int index)
       putc ('\n', stdout);
       errors = true;
     }
+
+  if (malloc_usable_size_valid)
+    {
+      size_t usable = malloc_usable_size (alloc->data);
+      if (usable < size)
+        {
+          printf ("error: allocation %d has reported size %zu (expected %zu)\n",
+                  index, usable, size);
+          errors = true;
+        }
+      else if (usable > size + 4096)
+        {
+          printf ("error: allocation %d reported as %zu bytes (requested %zu)\n",
+                  index, usable, size);
+          errors = true;
+        }
+    }
 }
 
 /* A heap allocation combined with pending actions on it.  */
@@ -317,6 +338,10 @@ init_heap (void)
       write_message ("error: malloc_set_state failed\n");
       _exit (1);
     }
+
+  /* The heap has been initialized.  We may now call
+     malloc_usable_size.  */
+  malloc_usable_size_valid = true;
 }
 
 /* Interpose the initialization callback.  */
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index f68fdf4..801ded8 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -607,6 +607,10 @@ struct rtld_global_ro
   /* List of auditing interfaces.  */
   struct audit_ifaces *_dl_audit;
   unsigned int _dl_naudit;
+
+  /* malloc protection keys. */
+  uintptr_t _dl_malloc_header_guard;
+  uintptr_t _dl_malloc_footer_guard;
 };
 # define __rtld_global_attribute__
 # if IS_IN (rtld)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=09fa7525b6c4318c93b9f224fd36c84173d6fcb2

commit 09fa7525b6c4318c93b9f224fd36c84173d6fcb2
Author: Florian Weimer <fweimer@redhat.com>
Date:   Fri Oct 28 17:01:56 2016 +0200

    Generate additional secret keys for the heap protector

diff --git a/ChangeLog b/ChangeLog
index 90f7eda..0068b47 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
 2016-10-28  Florian Weimer  <fweimer@redhat.com>
 
+	* elf/dl-keysetup.h: New file.
+	* elf/dl-keysetup.c: Likewise.
+	* elf/Makefile (dl-routines): Add dl-keysetup.
+	* csu/libc-start.c (LIBC_START_MAIN): Call __compute_keys to
+	obtain key material.
+	* elf/rtld.c (security_init): Likewise.
+	* crypt/sha256.c: Use relative #include for sha256-block.c
+	* sysdeps/generic/dl-osinfo.h (_dl_setup_stack_chk_guard)
+	(_dl_setup_pointer_guard): Remove.
+	* sysdeps/unix/sysv/linux/dl-osinfo.h (_dl_setup_stack_chk_guard)
+	(_dl_setup_pointer_guard): Likewise.
+
+2016-10-28  Florian Weimer  <fweimer@redhat.com>
+
 	* crypt/sha256.c, crypt/sha256-block.c,
 	sysdeps/sparc/sparc64/multiarch/sha256-block.c: Rename
 	sha256_process_block to __sha256_process_block.
diff --git a/crypt/sha256.c b/crypt/sha256.c
index b5497d9..a6ab2e1 100644
--- a/crypt/sha256.c
+++ b/crypt/sha256.c
@@ -211,4 +211,4 @@ __sha256_process_bytes (const void *buffer, size_t len, struct sha256_ctx *ctx)
     }
 }
 
-#include <sha256-block.c>
+#include "sha256-block.c"
diff --git a/csu/libc-start.c b/csu/libc-start.c
index 99c040a..333a4cc 100644
--- a/csu/libc-start.c
+++ b/csu/libc-start.c
@@ -21,6 +21,7 @@
 #include <unistd.h>
 #include <ldsodefs.h>
 #include <exit-thread.h>
+#include <elf/dl-keysetup.h>
 
 extern void __libc_init_first (int argc, char **argv, char **envp);
 
@@ -192,21 +193,21 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
      we need to setup errno.  */
   __pthread_initialize_minimal ();
 
+  struct key_setup keys;
+  __compute_keys (_dl_random, &keys);
+
   /* Set up the stack checker's canary.  */
-  uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random);
 # ifdef THREAD_SET_STACK_GUARD
-  THREAD_SET_STACK_GUARD (stack_chk_guard);
+  THREAD_SET_STACK_GUARD (keys.stack);
 # else
-  __stack_chk_guard = stack_chk_guard;
+  __stack_chk_guard = keys.stack;
 # endif
 
   /* Set up the pointer guard value.  */
-  uintptr_t pointer_chk_guard = _dl_setup_pointer_guard (_dl_random,
-							 stack_chk_guard);
 # ifdef THREAD_SET_POINTER_GUARD
-  THREAD_SET_POINTER_GUARD (pointer_chk_guard);
+  THREAD_SET_POINTER_GUARD (keys.pointer);
 # else
-  __pointer_chk_guard_local = pointer_chk_guard;
+  __pointer_chk_guard_local = keys.pointer;
 # endif
 
 #endif
diff --git a/elf/Makefile b/elf/Makefile
index 82c7e05..c0a8e2e 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -31,7 +31,8 @@ routines	= $(all-dl-routines) dl-support dl-iteratephdr \
 dl-routines	= $(addprefix dl-,load lookup object reloc deps hwcaps \
 				  runtime error init fini debug misc \
 				  version profile conflict tls origin scope \
-				  execstack caller open close trampoline)
+				  execstack caller open close trampoline \
+				  keysetup)
 ifeq (yes,$(use-ldconfig))
 dl-routines += dl-cache
 endif
diff --git a/elf/dl-keysetup.c b/elf/dl-keysetup.c
new file mode 100644
index 0000000..45bd4de
--- /dev/null
+++ b/elf/dl-keysetup.c
@@ -0,0 +1,77 @@
+/* Compute secret keys used for protection heuristics.
+   Copyright (C) 2016 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
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <dl-keysetup.h>
+#include <string.h>
+
+enum { at_random_size = 16 };
+
+#if __WORDSIZE == 64
+enum { sha256_output_size = 32 };
+static void compute_sha256_of_random (const void *random, void *result);
+#endif
+
+void
+__compute_keys (const void *random, struct key_setup *result)
+{
+#if __WORDSIZE == 32
+  _Static_assert (sizeof (*result) == at_random_size,
+                  "no key expansion required");
+  memcpy (random, result, sizeof (result));
+#else
+  /* We use SHA-256 to expand the 16 bytes of randomness into 32
+     bytes, so that it is hard to guess the remaining keys once a
+     subset of them is known.  */
+  _Static_assert (sizeof (*result) == sha256_output_size,
+                  "SHA-256 provides required size");
+  compute_sha256_of_random (random, result);
+#endif
+
+  /* Prevent leakage of the stack canary through a read buffer
+     overflow of a NUL-terminated string.  */
+  *(char *) &result->stack = '\0';
+
+  /* Clear the lowest three bits in the heap header guard value, so
+     that the flag bits remain unchanged.  */
+  result->heap_header <<= 3;
+}
+
+#if __WORDSIZE == 64
+
+#pragma GCC visibility push (hidden)
+
+/* Avoid symbol collisions with libcrypt.  */
+#define __sha256_process_block __dl_sha256_process_block
+#define __sha256_init_ctx __dl_sha256_init_ctx
+#define __sha256_process_bytes __dl_sha256_process_bytes
+#define __sha256_finish_ctx __dl_sha256_finish_ctx
+
+#include "../crypt/sha256.h"
+#include "../crypt/sha256.c"
+
+#pragma GCC visibility pop
+
+static void
+compute_sha256_of_random (const void *random, void *result)
+{
+  struct sha256_ctx ctx;
+  __sha256_init_ctx (&ctx);
+  __sha256_process_bytes (random, at_random_size, &ctx);
+  __sha256_finish_ctx (&ctx, result);
+}
+#endif
diff --git a/elf/dl-keysetup.h b/elf/dl-keysetup.h
new file mode 100644
index 0000000..6197b1d
--- /dev/null
+++ b/elf/dl-keysetup.h
@@ -0,0 +1,45 @@
+/* Compute secret keys used for protection heuristics.
+   Copyright (C) 2016 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
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef KEY_SETUP_H
+#define KEY_SETUP_H
+
+#include <stdint.h>
+
+/* The set of protection keys used by glibc.  */
+struct key_setup
+{
+  /* Canary for the stack-smashing protector.  */
+  uintptr_t stack;
+
+  /* Pointer guard, protecting selected function pointers.  */
+  uintptr_t pointer;
+
+  /* Heap guard, protecting the malloc chunk header.  */
+  uintptr_t heap_header;
+
+  /* Heap guard part two, protecting the previous chunk size field.  */
+  uintptr_t heap_footer;
+};
+
+/* Derive the keys in *RESULT from RANDOM, which comes from the
+   auxiliary vector and points to 16 bytes of randomness.  */
+void __compute_keys (const void *random, struct key_setup *result)
+  attribute_hidden;
+
+#endif /* KEY_SETUP_H */
diff --git a/elf/rtld.c b/elf/rtld.c
index 647661c..de965da 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -41,6 +41,7 @@
 #include <tls.h>
 #include <stap-probe.h>
 #include <stackinfo.h>
+#include <dl-keysetup.h>
 
 #include <assert.h>
 
@@ -699,21 +700,21 @@ rtld_lock_default_unlock_recursive (void *lock)
 static void
 security_init (void)
 {
+  struct key_setup keys;
+  __compute_keys (_dl_random, &keys);
+
   /* Set up the stack checker's canary.  */
-  uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random);
 #ifdef THREAD_SET_STACK_GUARD
-  THREAD_SET_STACK_GUARD (stack_chk_guard);
+  THREAD_SET_STACK_GUARD (keys.stack);
 #else
-  __stack_chk_guard = stack_chk_guard;
+  __stack_chk_guard = keys.stack;
 #endif
 
   /* Set up the pointer guard as well, if necessary.  */
-  uintptr_t pointer_chk_guard
-    = _dl_setup_pointer_guard (_dl_random, stack_chk_guard);
 #ifdef THREAD_SET_POINTER_GUARD
-  THREAD_SET_POINTER_GUARD (pointer_chk_guard);
+  THREAD_SET_POINTER_GUARD (keys.pointer);
 #endif
-  __pointer_chk_guard_local = pointer_chk_guard;
+  __pointer_chk_guard_local = keys.pointer;
 
   /* We do not need the _dl_random value anymore.  The less
      information we leave behind, the better, so clear the
diff --git a/sysdeps/generic/dl-osinfo.h b/sysdeps/generic/dl-osinfo.h
index 2489e7b..47464c2 100644
--- a/sysdeps/generic/dl-osinfo.h
+++ b/sysdeps/generic/dl-osinfo.h
@@ -16,44 +16,4 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <endian.h>
-#include <stdint.h>
-
-static inline uintptr_t __attribute__ ((always_inline))
-_dl_setup_stack_chk_guard (void *dl_random)
-{
-  union
-  {
-    uintptr_t num;
-    unsigned char bytes[sizeof (uintptr_t)];
-  } ret = { 0 };
-
-  if (dl_random == NULL)
-    {
-      ret.bytes[sizeof (ret) - 1] = 255;
-      ret.bytes[sizeof (ret) - 2] = '\n';
-    }
-  else
-    {
-      memcpy (ret.bytes, dl_random, sizeof (ret));
-#if BYTE_ORDER == LITTLE_ENDIAN
-      ret.num &= ~(uintptr_t) 0xff;
-#elif BYTE_ORDER == BIG_ENDIAN
-      ret.num &= ~((uintptr_t) 0xff << (8 * (sizeof (ret) - 1)));
-#else
-# error "BYTE_ORDER unknown"
-#endif
-    }
-  return ret.num;
-}
-
-static inline uintptr_t __attribute__ ((always_inline))
-_dl_setup_pointer_guard (void *dl_random, uintptr_t stack_chk_guard)
-{
-  uintptr_t ret;
-  if (dl_random == NULL)
-    ret = stack_chk_guard;
-  else
-    memcpy (&ret, (char *) dl_random + sizeof (ret), sizeof (ret));
-  return ret;
-}
+/* No operating-system specific code in the default version.  */
diff --git a/sysdeps/unix/sysv/linux/dl-osinfo.h b/sysdeps/unix/sysv/linux/dl-osinfo.h
index ac72c92..408cf5a 100644
--- a/sysdeps/unix/sysv/linux/dl-osinfo.h
+++ b/sysdeps/unix/sysv/linux/dl-osinfo.h
@@ -46,34 +46,3 @@
     else if (__LINUX_KERNEL_VERSION > 0)				      \
       FATAL ("FATAL: cannot determine kernel version\n");		      \
   } while (0)
-
-static inline uintptr_t __attribute__ ((always_inline))
-_dl_setup_stack_chk_guard (void *dl_random)
-{
-  union
-  {
-    uintptr_t num;
-    unsigned char bytes[sizeof (uintptr_t)];
-  } 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 &= ~(uintptr_t) 0xff;
-#elif BYTE_ORDER == BIG_ENDIAN
-  ret.num &= ~((uintptr_t) 0xff << (8 * (sizeof (ret) - 1)));
-#else
-# error "BYTE_ORDER unknown"
-#endif
-  return ret.num;
-}
-
-static inline uintptr_t __attribute__ ((always_inline))
-_dl_setup_pointer_guard (void *dl_random, uintptr_t stack_chk_guard)
-{
-  uintptr_t ret;
-  memcpy (&ret, (char *) dl_random + sizeof (ret), sizeof (ret));
-  return ret;
-}

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=3111495d687baa1d322c2ffd2042d43bf3c5f2b6

commit 3111495d687baa1d322c2ffd2042d43bf3c5f2b6
Author: Florian Weimer <fweimer@redhat.com>
Date:   Fri Oct 28 14:24:58 2016 +0200

    crypt: Use internal names for the SHA-2 block functions
    
    These functions are externally visible with a static libcrypt
    library.

diff --git a/ChangeLog b/ChangeLog
index b5626ed..90f7eda 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2016-10-28  Florian Weimer  <fweimer@redhat.com>
 
+	* crypt/sha256.c, crypt/sha256-block.c,
+	sysdeps/sparc/sparc64/multiarch/sha256-block.c: Rename
+	sha256_process_block to __sha256_process_block.
+	* crypt/sha512.c, crypt/sha512-block.c,
+	sysdeps/sparc/sparc64/multiarch/sha512-block.c: Rename
+	sha512_process_block to __sha512_process_block.
+
+2016-10-28  Florian Weimer  <fweimer@redhat.com>
+
 	[BZ #20729]
 	Support i386 builds with CFLAGS which imply -fno-omit-frame-pointer.
 	* sysdeps/unix/sysv/linux/i386/Makefile
diff --git a/crypt/sha256-block.c b/crypt/sha256-block.c
index 8a77096..a44fe01 100644
--- a/crypt/sha256-block.c
+++ b/crypt/sha256-block.c
@@ -3,7 +3,7 @@
 /* Process LEN bytes of BUFFER, accumulating context into CTX.
    It is assumed that LEN % 64 == 0.  */
 void
-sha256_process_block (const void *buffer, size_t len, struct sha256_ctx *ctx)
+__sha256_process_block (const void *buffer, size_t len, struct sha256_ctx *ctx)
 {
   const uint32_t *words = buffer;
   size_t nwords = len / sizeof (uint32_t);
diff --git a/crypt/sha256.c b/crypt/sha256.c
index e858f4b..b5497d9 100644
--- a/crypt/sha256.c
+++ b/crypt/sha256.c
@@ -81,8 +81,7 @@ static const uint32_t K[64] =
     0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
   };
 
-void
-sha256_process_block (const void *, size_t, struct sha256_ctx *);
+void __sha256_process_block (const void *, size_t, struct sha256_ctx *);
 
 /* Initialize structure containing state of computation.
    (FIPS 180-2:5.3.2)  */
@@ -131,7 +130,7 @@ __sha256_finish_ctx (struct sha256_ctx *ctx, void *resbuf)
 #endif
 
   /* Process last bytes.  */
-  sha256_process_block (ctx->buffer, bytes + pad + 8, ctx);
+  __sha256_process_block (ctx->buffer, bytes + pad + 8, ctx);
 
   /* Put result from CTX in first 32 bytes following RESBUF.  */
   for (unsigned int i = 0; i < 8; ++i)
@@ -156,7 +155,7 @@ __sha256_process_bytes (const void *buffer, size_t len, struct sha256_ctx *ctx)
 
       if (ctx->buflen > 64)
 	{
-	  sha256_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
+	  __sha256_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
 
 	  ctx->buflen &= 63;
 	  /* The regions in the following copy operation cannot overlap.  */
@@ -182,14 +181,14 @@ __sha256_process_bytes (const void *buffer, size_t len, struct sha256_ctx *ctx)
       if (UNALIGNED_P (buffer))
 	while (len > 64)
 	  {
-	    sha256_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
+	    __sha256_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
 	    buffer = (const char *) buffer + 64;
 	    len -= 64;
 	  }
       else
 #endif
 	{
-	  sha256_process_block (buffer, len & ~63, ctx);
+	  __sha256_process_block (buffer, len & ~63, ctx);
 	  buffer = (const char *) buffer + (len & ~63);
 	  len &= 63;
 	}
@@ -204,7 +203,7 @@ __sha256_process_bytes (const void *buffer, size_t len, struct sha256_ctx *ctx)
       left_over += len;
       if (left_over >= 64)
 	{
-	  sha256_process_block (ctx->buffer, 64, ctx);
+	  __sha256_process_block (ctx->buffer, 64, ctx);
 	  left_over -= 64;
 	  memcpy (ctx->buffer, &ctx->buffer[64], left_over);
 	}
diff --git a/crypt/sha512-block.c b/crypt/sha512-block.c
index c542db1..577839f 100644
--- a/crypt/sha512-block.c
+++ b/crypt/sha512-block.c
@@ -3,7 +3,7 @@
 /* Process LEN bytes of BUFFER, accumulating context into CTX.
    It is assumed that LEN % 128 == 0.  */
 void
-sha512_process_block (const void *buffer, size_t len, struct sha512_ctx *ctx)
+__sha512_process_block (const void *buffer, size_t len, struct sha512_ctx *ctx)
 {
   const uint64_t *words = buffer;
   size_t nwords = len / sizeof (uint64_t);
diff --git a/crypt/sha512.c b/crypt/sha512.c
index 47f3f7c..dd2af3c 100644
--- a/crypt/sha512.c
+++ b/crypt/sha512.c
@@ -101,8 +101,8 @@ static const uint64_t K[80] =
     UINT64_C (0x5fcb6fab3ad6faec), UINT64_C (0x6c44198c4a475817)
   };
 
-void
-sha512_process_block (const void *buffer, size_t len, struct sha512_ctx *ctx);
+void __sha512_process_block (const void *buffer, size_t len,
+			     struct sha512_ctx *ctx);
 
 /* Initialize structure containing state of computation.
    (FIPS 180-2:5.3.3)  */
@@ -153,7 +153,7 @@ __sha512_finish_ctx (struct sha512_ctx *ctx, void *resbuf)
 					   (ctx->total[TOTAL128_low] >> 61));
 
   /* Process last bytes.  */
-  sha512_process_block (ctx->buffer, bytes + pad + 16, ctx);
+  __sha512_process_block (ctx->buffer, bytes + pad + 16, ctx);
 
   /* Put result from CTX in first 64 bytes following RESBUF.  */
   for (unsigned int i = 0; i < 8; ++i)
@@ -178,7 +178,7 @@ __sha512_process_bytes (const void *buffer, size_t len, struct sha512_ctx *ctx)
 
       if (ctx->buflen > 128)
 	{
-	  sha512_process_block (ctx->buffer, ctx->buflen & ~127, ctx);
+	  __sha512_process_block (ctx->buffer, ctx->buflen & ~127, ctx);
 
 	  ctx->buflen &= 127;
 	  /* The regions in the following copy operation cannot overlap.  */
@@ -204,7 +204,7 @@ __sha512_process_bytes (const void *buffer, size_t len, struct sha512_ctx *ctx)
       if (UNALIGNED_P (buffer))
 	while (len > 128)
 	  {
-	    sha512_process_block (memcpy (ctx->buffer, buffer, 128), 128,
+	    __sha512_process_block (memcpy (ctx->buffer, buffer, 128), 128,
 				    ctx);
 	    buffer = (const char *) buffer + 128;
 	    len -= 128;
@@ -212,7 +212,7 @@ __sha512_process_bytes (const void *buffer, size_t len, struct sha512_ctx *ctx)
       else
 #endif
 	{
-	  sha512_process_block (buffer, len & ~127, ctx);
+	  __sha512_process_block (buffer, len & ~127, ctx);
 	  buffer = (const char *) buffer + (len & ~127);
 	  len &= 127;
 	}
@@ -227,7 +227,7 @@ __sha512_process_bytes (const void *buffer, size_t len, struct sha512_ctx *ctx)
       left_over += len;
       if (left_over >= 128)
 	{
-	  sha512_process_block (ctx->buffer, 128, ctx);
+	  __sha512_process_block (ctx->buffer, 128, ctx);
 	  left_over -= 128;
 	  memcpy (ctx->buffer, &ctx->buffer[128], left_over);
 	}
diff --git a/sysdeps/sparc/sparc64/multiarch/sha256-block.c b/sysdeps/sparc/sparc64/multiarch/sha256-block.c
index 79966b9..aa57662 100644
--- a/sysdeps/sparc/sparc64/multiarch/sha256-block.c
+++ b/sysdeps/sparc/sparc64/multiarch/sha256-block.c
@@ -1,12 +1,12 @@
 #include <sparc-ifunc.h>
 
-#define sha256_process_block sha256_process_block_generic
-extern void sha256_process_block_generic (const void *buffer, size_t len,
-					  struct sha256_ctx *ctx);
+#define __sha256_process_block __sha256_process_block_generic
+extern void __sha256_process_block_generic (const void *buffer, size_t len,
+					    struct sha256_ctx *ctx);
 
 #include <crypt/sha256-block.c>
 
-#undef sha256_process_block
+#undef __sha256_process_block
 
 extern void __sha256_process_block_crop (const void *buffer, size_t len,
 					 struct sha256_ctx *ctx);
@@ -25,6 +25,8 @@ static bool cpu_supports_sha256(int hwcap)
   return false;
 }
 
-extern void sha256_process_block (const void *buffer, size_t len,
-				  struct sha256_ctx *ctx);
-sparc_libc_ifunc(sha256_process_block, cpu_supports_sha256(hwcap) ? __sha256_process_block_crop : sha256_process_block_generic);
+extern void __sha256_process_block (const void *buffer, size_t len,
+				    struct sha256_ctx *ctx);
+sparc_libc_ifunc (__sha256_process_block,
+		  cpu_supports_sha256(hwcap) ? __sha256_process_block_crop
+		    : sha256_process_block_generic);
diff --git a/sysdeps/sparc/sparc64/multiarch/sha512-block.c b/sysdeps/sparc/sparc64/multiarch/sha512-block.c
index 0d1c3dd..2863e05 100644
--- a/sysdeps/sparc/sparc64/multiarch/sha512-block.c
+++ b/sysdeps/sparc/sparc64/multiarch/sha512-block.c
@@ -1,12 +1,12 @@
 #include <sparc-ifunc.h>
 
-#define sha512_process_block sha512_process_block_generic
-extern void sha512_process_block_generic (const void *buffer, size_t len,
-					  struct sha512_ctx *ctx);
+#define __sha512_process_block __sha512_process_block_generic
+extern void __sha512_process_block_generic (const void *buffer, size_t len,
+					    struct sha512_ctx *ctx);
 
 #include <crypt/sha512-block.c>
 
-#undef sha512_process_block
+#undef __sha512_process_block
 
 extern void __sha512_process_block_crop (const void *buffer, size_t len,
 					 struct sha512_ctx *ctx);
@@ -25,6 +25,8 @@ static bool cpu_supports_sha512(int hwcap)
   return false;
 }
 
-extern void sha512_process_block (const void *buffer, size_t len,
-				  struct sha512_ctx *ctx);
-sparc_libc_ifunc(sha512_process_block, cpu_supports_sha512(hwcap) ? __sha512_process_block_crop : sha512_process_block_generic);
+extern void __sha512_process_block (const void *buffer, size_t len,
+				    struct sha512_ctx *ctx);
+sparc_libc_ifunc (__sha512_process_block,
+		  cpu_supports_sha512(hwcap) ? __sha512_process_block_crop
+		    : __sha512_process_block_generic);

-----------------------------------------------------------------------


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]