diff --git a/programs/test/metatest.c b/programs/test/metatest.c index 6ab240c592..a3d9d4095a 100644 --- a/programs/test/metatest.c +++ b/programs/test/metatest.c @@ -332,6 +332,13 @@ metatest_t metatests[] = { { "read_uninitialized_stack", "msan", read_uninitialized_stack }, { "memory_leak", "asan", memory_leak }, { "test_memory_poison_0_0_8", "asan", test_memory_poison }, + { "test_memory_poison_0_7_8", "asan", test_memory_poison }, + { "test_memory_poison_0_0_1", "asan", test_memory_poison }, + { "test_memory_poison_0_1_2", "asan", test_memory_poison }, + { "test_memory_poison_7_0_8", "asan", test_memory_poison }, + { "test_memory_poison_7_7_8", "asan", test_memory_poison }, + { "test_memory_poison_7_0_1", "asan", test_memory_poison }, + { "test_memory_poison_7_1_2", "asan", test_memory_poison }, { "mutex_lock_not_initialized", "pthread", mutex_lock_not_initialized }, { "mutex_unlock_not_initialized", "pthread", mutex_unlock_not_initialized }, { "mutex_free_not_initialized", "pthread", mutex_free_not_initialized }, diff --git a/tests/include/test/memory.h b/tests/include/test/memory.h index 27baf7a1dc..f610a97a45 100644 --- a/tests/include/test/memory.h +++ b/tests/include/test/memory.h @@ -40,6 +40,10 @@ * Poison a memory area so that any attempt to read or write from it will * cause a runtime failure. * + * Depending on the implementation, this may poison a few bytes beyond the + * indicated region, but will never poison a separate object on the heap + * or a separate object with more than the alignment of a long long. + * * The behavior is undefined if any part of the memory area is invalid. * * This is a no-op in builds without a poisoning method. diff --git a/tests/src/test_memory.c b/tests/src/test_memory.c index 6b1404bc3c..c277be85ab 100644 --- a/tests/src/test_memory.c +++ b/tests/src/test_memory.c @@ -19,11 +19,27 @@ #endif #if defined(MBEDTLS_TEST_HAVE_ASAN) +static void align_for_asan(const unsigned char **p_ptr, size_t *p_size) +{ + uintptr_t start = (uintptr_t) *p_ptr; + uintptr_t end = start + (uintptr_t) *p_size; + /* ASan can only poison regions with 8-byte alignment, and only poisons a + * region if it's fully within the requested range. We want to poison the + * whole requested region and don't mind a few extra bytes. Therefore, + * align start down to an 8-byte boundary, and end up to an 8-byte + * boundary. */ + start = start & ~(uintptr_t) 7; + end = (end + 7) & ~(uintptr_t) 7; + *p_ptr = (const unsigned char *) start; + *p_size = end - start; +} + void mbedtls_test_memory_poison(const unsigned char *ptr, size_t size) { if (size == 0) { return; } + align_for_asan(&ptr, &size); __asan_poison_memory_region(ptr, size); } @@ -32,6 +48,7 @@ void mbedtls_test_memory_unpoison(const unsigned char *ptr, size_t size) if (size == 0) { return; } + align_for_asan(&ptr, &size); __asan_unpoison_memory_region(ptr, size); } #endif /* Asan */