summaryrefslogtreecommitdiff
path: root/libc/stdlib/malloc-standard/malloc.h
diff options
context:
space:
mode:
authorEyal Itkin <eyalit@checkpoint.com>2019-12-27 18:45:20 +0200
committerWaldemar Brodkorb <wbx@openadk.org>2020-02-16 12:32:21 +0100
commit886878b22424d6f95bcdeee55ada72049d21547c (patch)
treec1ca8f9ac64bb6750e8b949635ec87963b454848 /libc/stdlib/malloc-standard/malloc.h
parent90f24fc94897d93deb80d933d18a4f31dc6bf05a (diff)
Add Safe-Linking to fastbins
Safe-Linking is a security mechanism that protects single-linked lists (such as the fastbins) from being tampered by attackers. The mechanism makes use of randomness from ASLR (mmap_base), and when combined with chunk alignment integrity checks, it protects the pointers from being hijacked by an attacker. While Safe-Unlinking protects double-linked lists (such as the small bins), there wasn't any similar protection for attacks against single-linked lists. This solution protects against 3 common attacks: * Partial pointer override: modifies the lower bytes (Little Endian) * Full pointer override: hijacks the pointer to an attacker's location * Unaligned chunks: pointing the list to an unaligned address The design assumes an attacker doesn't know where the heap is located, and uses the ASLR randomness to "sign" the single-linked pointers. We mark the pointer as P and the location in which it is stored as L, and the calculation will be: * PROTECT(P) := (L >> PAGE_SHIFT) XOR (P) * *L = PROTECT(P) This way, the random bits from the address L (which start at the bits in the PAGE_SHIFT position), will be merged with the LSB of the stored protected pointer. This protection layer prevents an attacker from modifying the pointer into a controlled value. An additional check that the chunks are MALLOC_ALIGNed adds an important layer: * Attackers can't point to illegal (unaligned) memory addresses * Attackers must guess correctly the alignment bits On standard 32 bit Linux machines, an attacker will directly fail 7 out of 8 times, and on 64 bit machines it will fail 15 out of 16 times. The proposed solution adds 3-4 asm instructions per malloc()/free() and therefore has only minor performance implications if it has any. A similar protection was added to Chromium's version of TCMalloc in 2013, and according to their documentation the performance overhead was less than 2%. Signed-off-by: Eyal Itkin <eyalit@checkpoint.com>
Diffstat (limited to 'libc/stdlib/malloc-standard/malloc.h')
-rw-r--r--libc/stdlib/malloc-standard/malloc.h12
1 files changed, 12 insertions, 0 deletions
diff --git a/libc/stdlib/malloc-standard/malloc.h b/libc/stdlib/malloc-standard/malloc.h
index 44120d388..30a696e5a 100644
--- a/libc/stdlib/malloc-standard/malloc.h
+++ b/libc/stdlib/malloc-standard/malloc.h
@@ -839,6 +839,18 @@ typedef struct malloc_chunk* mfastbinptr;
#define get_max_fast(M) \
((M)->max_fast & ~(FASTCHUNKS_BIT | ANYCHUNKS_BIT))
+/*
+ Safe-Linking:
+ Use randomness from ASLR (mmap_base) to protect single-linked lists
+ of fastbins. Together with allocation alignment checks, this mechanism
+ reduces the risk of pointer hijacking, as was done with Safe-Unlinking
+ in the double-linked lists of smallbins.
+*/
+#define PROTECT_PTR(pos, ptr) ((mchunkptr)((((size_t)pos) >> PAGE_SHIFT) ^ ((size_t)ptr)))
+#define REVEAL_PTR(pos, ptr) PROTECT_PTR(pos, ptr)
+#define CHECK_PTR(P) \
+ if (!aligned_OK(P)) \
+ abort();
/*
morecore_properties is a status word holding dynamically discovered