From b24569b6ca8265d21e2266016fe9245b33b45343 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Wed, 3 Oct 2018 17:09:57 -0400 Subject: [PATCH] zero leading byte of canaries --- README.md | 1 + malloc.c | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9e3103d..b324c60 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,7 @@ allocation and then unmapped on free. * Random canaries placed after each slab allocation to *absorb* and then later detect overflows/underflows * High entropy per-slab random values + * Leading byte is zeroed to contain C string overflows * [in-progress] Mangled into a unique value per slab slot (although not with a strong keyed hash due to performance limitations) * Possible slab locations are skipped and remain memory protected, leaving slab diff --git a/malloc.c b/malloc.c index a000acd..18772c7 100644 --- a/malloc.c +++ b/malloc.c @@ -274,6 +274,12 @@ static void write_after_free_check(char *p, size_t size) { } } +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +static const uint64_t canary_mask = 0xffffffffffffff00UL; +#else +static const uint64_t canary_mask = 0x00ffffffffffffffUL; +#endif + static void set_canary(struct slab_metadata *metadata, void *p, size_t size) { memcpy((char *)p + size - canary_size, &metadata->canary_value, canary_size); } @@ -345,7 +351,7 @@ static inline void *allocate_small(size_t requested_size) { mutex_unlock(&c->lock); return NULL; } - metadata->canary_value = get_random_u64(&c->rng); + metadata->canary_value = get_random_u64(&c->rng) & canary_mask; c->partial_slabs = metadata; void *slab = get_slab(c, slab_size, metadata);