From da8bb847fd9aa9b029bf0383cbe0de9796495c1a Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Tue, 26 Feb 2019 22:13:28 -0600 Subject: [PATCH] Tell ASan about the OPENSSL_malloc prefix. OpenSSL's BN_mul function had a single-word buffer underflow (see 576129cd72ae054d246221f111aabf42b9c6d76d). We already independently fixed this but, if we hadn't, ASan wouldn't have noticed because of OPENSSL_malloc. ASan has runtime hooks we can call to make it more accurate. Change-Id: Ifc9c3837ece2bc456c5bdc960be707d7b1759904 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/35165 Reviewed-by: Adam Langley --- crypto/mem.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/crypto/mem.c b/crypto/mem.c index 6af532ee..14e0bdf3 100644 --- a/crypto/mem.c +++ b/crypto/mem.c @@ -71,6 +71,14 @@ OPENSSL_MSVC_PRAGMA(warning(pop)) #define OPENSSL_MALLOC_PREFIX 8 +#if defined(OPENSSL_ASAN) +void __asan_poison_memory_region(const volatile void *addr, size_t size); +void __asan_unpoison_memory_region(const volatile void *addr, size_t size); +#else +static void __asan_poison_memory_region(const void *addr, size_t size) {} +static void __asan_unpoison_memory_region(const void *addr, size_t size) {} +#endif + #if defined(__GNUC__) || defined(__clang__) // sdallocx is a sized |free| function. By passing the size (which we happen to // always know in BoringSSL), the malloc implementation can save work. We cannot @@ -99,6 +107,7 @@ void *OPENSSL_malloc(size_t size) { *(size_t *)ptr = size; + __asan_poison_memory_region(ptr, OPENSSL_MALLOC_PREFIX); return ((uint8_t *)ptr) + OPENSSL_MALLOC_PREFIX; } @@ -108,6 +117,7 @@ void OPENSSL_free(void *orig_ptr) { } void *ptr = ((uint8_t *)orig_ptr) - OPENSSL_MALLOC_PREFIX; + __asan_unpoison_memory_region(ptr, OPENSSL_MALLOC_PREFIX); size_t size = *(size_t *)ptr; OPENSSL_cleanse(ptr, size + OPENSSL_MALLOC_PREFIX); @@ -120,7 +130,9 @@ void *OPENSSL_realloc(void *orig_ptr, size_t new_size) { } void *ptr = ((uint8_t *)orig_ptr) - OPENSSL_MALLOC_PREFIX; + __asan_unpoison_memory_region(ptr, OPENSSL_MALLOC_PREFIX); size_t old_size = *(size_t *)ptr; + __asan_poison_memory_region(ptr, OPENSSL_MALLOC_PREFIX); void *ret = OPENSSL_malloc(new_size); if (ret == NULL) {