From 7430d2335826665099398ce289a870f9d4b73516 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 17 Sep 2019 18:18:58 +0200 Subject: [PATCH] Add a calloc self-test Add a very basic test of calloc to the selftest program. The selftest program acts in its capacity as a platform compatibility checker rather than in its capacity as a test of the library. The main objective is to report whether calloc returns NULL for a size of 0. Also observe whether a free/alloc sequence returns the address that was just freed and whether a size overflow is properly detected. --- programs/test/selftest.c | 83 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/programs/test/selftest.c b/programs/test/selftest.c index 727054ee6..bd28e9a36 100644 --- a/programs/test/selftest.c +++ b/programs/test/selftest.c @@ -66,6 +66,8 @@ #else #include #include +#define mbedtls_calloc calloc +#define mbedtls_free free #define mbedtls_printf printf #define mbedtls_snprintf snprintf #define mbedtls_exit exit @@ -78,6 +80,86 @@ #endif +#if defined MBEDTLS_SELF_TEST +/* Sanity check for malloc. This is not expected to fail, and is rather + * intended to display potentially useful information about the platform, + * in particular the behavior of malloc(0). */ +static int calloc_self_test( int verbose ) +{ + int failures = 0; + void *empty1 = mbedtls_calloc( 0, 1 ); + void *empty2 = mbedtls_calloc( 0, 1 ); + void *buffer1 = mbedtls_calloc( 1, 1 ); + void *buffer2 = mbedtls_calloc( 1, 1 ); + uintptr_t old_buffer1; + + if( empty1 == NULL && empty2 == NULL ) + { + if( verbose ) + mbedtls_printf( " CALLOC(0): passed (NULL)\n" ); + } + else if( empty1 == NULL || empty2 == NULL ) + { + if( verbose ) + mbedtls_printf( " CALLOC(0): failed (mix of NULL and non-NULL)\n" ); + ++failures; + } + else if( empty1 == empty2 ) + { + if( verbose ) + mbedtls_printf( " CALLOC(0): passed (same non-null)\n" ); + } + else + { + if( verbose ) + mbedtls_printf( " CALLOC(0): passed (distinct non-null)\n" ); + } + + if( buffer1 == NULL || buffer2 == NULL ) + { + if( verbose ) + mbedtls_printf( " CALLOC(1): failed (NULL)\n" ); + ++failures; + } + else if( buffer1 == buffer2 ) + { + if( verbose ) + mbedtls_printf( " CALLOC(1): failed (same buffer twice)\n" ); + ++failures; + } + else + { + if( verbose ) + mbedtls_printf( " CALLOC(1): passed\n" ); + } + + old_buffer1 = (uintptr_t) buffer1; + mbedtls_free( buffer1 ); + buffer1 = mbedtls_calloc( 1, 1 ); + if( buffer1 == NULL ) + { + if( verbose ) + mbedtls_printf( " CALLOC(1 again): failed (NULL)\n" ); + ++failures; + } + else + { + if( verbose ) + mbedtls_printf( " CALLOC(1 again): passed (%s address)\n", + (uintptr_t) old_buffer1 == (uintptr_t) buffer1 ? + "same" : "different" ); + } + + if( verbose ) + mbedtls_printf( "\n" ); + mbedtls_free( empty1 ); + mbedtls_free( empty2 ); + mbedtls_free( buffer1 ); + mbedtls_free( buffer2 ); + return( failures ); +} +#endif /* MBEDTLS_SELF_TEST */ + static int test_snprintf( size_t n, const char ref_buf[10], int ref_ret ) { int ret; @@ -174,6 +256,7 @@ typedef struct const selftest_t selftests[] = { + {"calloc", calloc_self_test}, #if defined(MBEDTLS_MD2_C) {"md2", mbedtls_md2_self_test}, #endif