about summary refs log tree commit diff
path: root/malloc/arena.c
diff options
context:
space:
mode:
authorSiddhesh Poyarekar <siddhesh@sourceware.org>2021-07-07 23:02:46 +0530
committerSiddhesh Poyarekar <siddhesh@sourceware.org>2021-07-08 01:39:38 +0530
commitfc859c304898a5ec72e0ba5269ed136ed0ea10e1 (patch)
treef060c61e0954f04cf4d01df4a7bc1a56e3cf5a70 /malloc/arena.c
parentf9c8b11ed7726b858cd7b7cea0d3d7c5233d78cf (diff)
downloadglibc-fc859c304898a5ec72e0ba5269ed136ed0ea10e1.tar.gz
glibc-fc859c304898a5ec72e0ba5269ed136ed0ea10e1.tar.xz
glibc-fc859c304898a5ec72e0ba5269ed136ed0ea10e1.zip
Harden tcache double-free check
The tcache allocator layer uses the tcache pointer as a key to
identify a block that may be freed twice.  Since this is in the
application data area, an attacker exploiting a use-after-free could
potentially get access to the entire tcache structure through this
key.  A detailed write-up was provided by Awarau here:

https://awaraucom.wordpress.com/2020/07/19/house-of-io-remastered/

Replace this static pointer use for key checking with one that is
generated at malloc initialization.  The first attempt is through
getrandom with a fallback to random_bits(), which is a simple
pseudo-random number generator based on the clock.  The fallback ought
to be sufficient since the goal of the randomness is only to make the
key arbitrary enough that it is very unlikely to collide with user
data.

Co-authored-by: Eyal Itkin <eyalit@checkpoint.com>
Diffstat (limited to 'malloc/arena.c')
-rw-r--r--malloc/arena.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/malloc/arena.c b/malloc/arena.c
index 7eb110445e..991fc21a7e 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -287,6 +287,10 @@ extern struct dl_open_hook *_dl_open_hook;
 libc_hidden_proto (_dl_open_hook);
 #endif
 
+#if USE_TCACHE
+static void tcache_key_initialize (void);
+#endif
+
 static void
 ptmalloc_init (void)
 {
@@ -295,6 +299,10 @@ ptmalloc_init (void)
 
   __malloc_initialized = 0;
 
+#if USE_TCACHE
+  tcache_key_initialize ();
+#endif
+
 #ifdef USE_MTAG
   if ((TUNABLE_GET_FULL (glibc, mem, tagging, int32_t, NULL) & 1) != 0)
     {