Merge pull request #7486 from AndrzejKurek/calloc-also-zeroizes
Document mbedtls_calloc zeroization
This commit is contained in:
commit
796bc2b8f9
8 changed files with 161 additions and 11 deletions
12
.travis.yml
12
.travis.yml
|
@ -32,6 +32,10 @@ jobs:
|
|||
packages:
|
||||
- clang-10
|
||||
- gnutls-bin
|
||||
env:
|
||||
# Platform tests have an allocation that returns null
|
||||
- ASAN_OPTIONS="allocator_may_return_null=1"
|
||||
- MSAN_OPTIONS="allocator_may_return_null=1"
|
||||
script:
|
||||
# Do a manual build+test sequence rather than using all.sh,
|
||||
# because there's no all.sh component that does what we want,
|
||||
|
@ -89,6 +93,10 @@ jobs:
|
|||
apt:
|
||||
packages:
|
||||
- gcc
|
||||
env:
|
||||
# Platform tests have an allocation that returns null
|
||||
- ASAN_OPTIONS="allocator_may_return_null=1"
|
||||
- MSAN_OPTIONS="allocator_may_return_null=1"
|
||||
script:
|
||||
# Do a manual build+test sequence rather than using all.sh.
|
||||
#
|
||||
|
@ -115,6 +123,10 @@ jobs:
|
|||
packages:
|
||||
- clang
|
||||
- gnutls-bin
|
||||
env:
|
||||
# Platform tests have an allocation that returns null
|
||||
- ASAN_OPTIONS="allocator_may_return_null=1"
|
||||
- MSAN_OPTIONS="allocator_may_return_null=1"
|
||||
script:
|
||||
# Do a manual build+test sequence rather than using all.sh.
|
||||
#
|
||||
|
|
|
@ -51,4 +51,5 @@ PREDEFINED = "MBEDTLS_CHECK_RETURN_CRITICAL=" \
|
|||
"MBEDTLS_CHECK_RETURN_TYPICAL=" \
|
||||
"MBEDTLS_CHECK_RETURN_OPTIONAL=" \
|
||||
"MBEDTLS_PRINTF_ATTRIBUTE(a,b)=" \
|
||||
"__DOXYGEN__" \
|
||||
|
||||
|
|
|
@ -172,15 +172,47 @@
|
|||
* This allows different allocators (self-implemented or provided) to be
|
||||
* provided to the platform abstraction layer.
|
||||
*
|
||||
* Enabling MBEDTLS_PLATFORM_MEMORY without the
|
||||
* Enabling #MBEDTLS_PLATFORM_MEMORY without the
|
||||
* MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide
|
||||
* "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and
|
||||
* free() function pointer at runtime.
|
||||
*
|
||||
* Enabling MBEDTLS_PLATFORM_MEMORY and specifying
|
||||
* Enabling #MBEDTLS_PLATFORM_MEMORY and specifying
|
||||
* MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the
|
||||
* alternate function at compile time.
|
||||
*
|
||||
* An overview of how the value of mbedtls_calloc is determined:
|
||||
*
|
||||
* - if !MBEDTLS_PLATFORM_MEMORY
|
||||
* - mbedtls_calloc = calloc
|
||||
* - if MBEDTLS_PLATFORM_MEMORY
|
||||
* - if (MBEDTLS_PLATFORM_CALLOC_MACRO && MBEDTLS_PLATFORM_FREE_MACRO):
|
||||
* - mbedtls_calloc = MBEDTLS_PLATFORM_CALLOC_MACRO
|
||||
* - if !(MBEDTLS_PLATFORM_CALLOC_MACRO && MBEDTLS_PLATFORM_FREE_MACRO):
|
||||
* - Dynamic setup via mbedtls_platform_set_calloc_free is now possible with a default value MBEDTLS_PLATFORM_STD_CALLOC.
|
||||
* - How is MBEDTLS_PLATFORM_STD_CALLOC handled?
|
||||
* - if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS:
|
||||
* - MBEDTLS_PLATFORM_STD_CALLOC is not set to anything;
|
||||
* - MBEDTLS_PLATFORM_STD_MEM_HDR can be included if present;
|
||||
* - if !MBEDTLS_PLATFORM_NO_STD_FUNCTIONS:
|
||||
* - if MBEDTLS_PLATFORM_STD_CALLOC is present:
|
||||
* - User-defined MBEDTLS_PLATFORM_STD_CALLOC is respected;
|
||||
* - if !MBEDTLS_PLATFORM_STD_CALLOC:
|
||||
* - MBEDTLS_PLATFORM_STD_CALLOC = calloc
|
||||
*
|
||||
* - At this point the presence of MBEDTLS_PLATFORM_STD_CALLOC is checked.
|
||||
* - if !MBEDTLS_PLATFORM_STD_CALLOC
|
||||
* - MBEDTLS_PLATFORM_STD_CALLOC = uninitialized_calloc
|
||||
*
|
||||
* - mbedtls_calloc = MBEDTLS_PLATFORM_STD_CALLOC.
|
||||
*
|
||||
* Defining MBEDTLS_PLATFORM_CALLOC_MACRO and #MBEDTLS_PLATFORM_STD_CALLOC at the same time is not possible.
|
||||
* MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_FREE_MACRO must both be defined or undefined at the same time.
|
||||
* #MBEDTLS_PLATFORM_STD_CALLOC and #MBEDTLS_PLATFORM_STD_FREE do not have to be defined at the same time, as, if they are used,
|
||||
* dynamic setup of these functions is possible. See the tree above to see how are they handled in all cases.
|
||||
* An uninitialized #MBEDTLS_PLATFORM_STD_CALLOC always fails, returning a null pointer.
|
||||
* An uninitialized #MBEDTLS_PLATFORM_STD_FREE does not do anything.
|
||||
*
|
||||
* Requires: MBEDTLS_PLATFORM_C
|
||||
*
|
||||
* Enable this layer to allow use of alternative memory allocators.
|
||||
|
@ -3708,8 +3740,29 @@
|
|||
|
||||
/* Platform options */
|
||||
//#define MBEDTLS_PLATFORM_STD_MEM_HDR <stdlib.h> /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */
|
||||
//#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use, can be undefined */
|
||||
//#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */
|
||||
|
||||
/** \def MBEDTLS_PLATFORM_STD_CALLOC
|
||||
*
|
||||
* Default allocator to use, can be undefined.
|
||||
* It must initialize the allocated buffer memory to zeroes.
|
||||
* The size of the buffer is the product of the two parameters.
|
||||
* The calloc function returns either a null pointer or a pointer to the allocated space.
|
||||
* If the product is 0, the function may either return NULL or a valid pointer to an array of size 0 which is a valid input to the deallocation function.
|
||||
* An uninitialized #MBEDTLS_PLATFORM_STD_CALLOC always fails, returning a null pointer.
|
||||
* See the description of #MBEDTLS_PLATFORM_MEMORY for more details.
|
||||
* The corresponding deallocation function is #MBEDTLS_PLATFORM_STD_FREE.
|
||||
*/
|
||||
//#define MBEDTLS_PLATFORM_STD_CALLOC calloc
|
||||
|
||||
/** \def MBEDTLS_PLATFORM_STD_FREE
|
||||
*
|
||||
* Default free to use, can be undefined.
|
||||
* NULL is a valid parameter, and the function must do nothing.
|
||||
* A non-null parameter will always be a pointer previously returned by #MBEDTLS_PLATFORM_STD_CALLOC and not yet freed.
|
||||
* An uninitialized #MBEDTLS_PLATFORM_STD_FREE does not do anything.
|
||||
* See the description of #MBEDTLS_PLATFORM_MEMORY for more details (same principles as for MBEDTLS_PLATFORM_STD_CALLOC apply).
|
||||
*/
|
||||
//#define MBEDTLS_PLATFORM_STD_FREE free
|
||||
//#define MBEDTLS_PLATFORM_STD_SETBUF setbuf /**< Default setbuf to use, can be undefined */
|
||||
//#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */
|
||||
//#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
|
||||
|
@ -3723,10 +3776,10 @@
|
|||
//#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
|
||||
//#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" /**< Seed file to read/write with default implementation */
|
||||
|
||||
/* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */
|
||||
/* To use the following function macros, MBEDTLS_PLATFORM_C must be enabled. */
|
||||
/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */
|
||||
//#define MBEDTLS_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined */
|
||||
//#define MBEDTLS_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined */
|
||||
//#define MBEDTLS_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined. See MBEDTLS_PLATFORM_STD_CALLOC for requirements. */
|
||||
//#define MBEDTLS_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined. See MBEDTLS_PLATFORM_STD_FREE for requirements. */
|
||||
//#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */
|
||||
//#define MBEDTLS_PLATFORM_SETBUF_MACRO setbuf /**< Default setbuf macro to use, can be undefined */
|
||||
//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
|
||||
|
|
|
@ -130,11 +130,22 @@ extern "C" {
|
|||
#endif
|
||||
#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
|
||||
|
||||
/* Enable certain documented defines only when generating doxygen to avoid
|
||||
* an "unrecognized define" error. */
|
||||
#if defined(__DOXYGEN__) && !defined(MBEDTLS_PLATFORM_STD_CALLOC)
|
||||
#define MBEDTLS_PLATFORM_STD_CALLOC
|
||||
#endif
|
||||
|
||||
#if defined(__DOXYGEN__) && !defined(MBEDTLS_PLATFORM_STD_FREE)
|
||||
#define MBEDTLS_PLATFORM_STD_FREE
|
||||
#endif
|
||||
|
||||
/** \} name SECTION: Module settings */
|
||||
|
||||
/*
|
||||
* The function pointers for calloc and free.
|
||||
* Please see MBEDTLS_PLATFORM_STD_CALLOC and MBEDTLS_PLATFORM_STD_FREE
|
||||
* in mbedtls_config.h for more information about behaviour and requirements.
|
||||
*/
|
||||
#if defined(MBEDTLS_PLATFORM_MEMORY)
|
||||
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \
|
||||
|
|
|
@ -73,23 +73,51 @@ static int calloc_self_test(int verbose)
|
|||
void *empty2 = mbedtls_calloc(0, 1);
|
||||
void *buffer1 = mbedtls_calloc(1, 1);
|
||||
void *buffer2 = mbedtls_calloc(1, 1);
|
||||
unsigned int buffer_3_size = 256;
|
||||
unsigned int buffer_4_size = 4097; /* Allocate more than the usual page size */
|
||||
unsigned char *buffer3 = mbedtls_calloc(buffer_3_size, 1);
|
||||
unsigned char *buffer4 = mbedtls_calloc(buffer_4_size, 1);
|
||||
|
||||
if (empty1 == NULL && empty2 == NULL) {
|
||||
if (verbose) {
|
||||
mbedtls_printf(" CALLOC(0): passed (NULL)\n");
|
||||
mbedtls_printf(" CALLOC(0,1): passed (NULL)\n");
|
||||
}
|
||||
} else if (empty1 == NULL || empty2 == NULL) {
|
||||
if (verbose) {
|
||||
mbedtls_printf(" CALLOC(0): failed (mix of NULL and non-NULL)\n");
|
||||
mbedtls_printf(" CALLOC(0,1): failed (mix of NULL and non-NULL)\n");
|
||||
}
|
||||
++failures;
|
||||
} else if (empty1 == empty2) {
|
||||
if (verbose) {
|
||||
mbedtls_printf(" CALLOC(0): passed (same non-null)\n");
|
||||
mbedtls_printf(" CALLOC(0,1): passed (same non-null)\n");
|
||||
}
|
||||
} else {
|
||||
if (verbose) {
|
||||
mbedtls_printf(" CALLOC(0): passed (distinct non-null)\n");
|
||||
mbedtls_printf(" CALLOC(0,1): passed (distinct non-null)\n");
|
||||
}
|
||||
}
|
||||
|
||||
mbedtls_free(empty1);
|
||||
mbedtls_free(empty2);
|
||||
|
||||
empty1 = mbedtls_calloc(1, 0);
|
||||
empty2 = mbedtls_calloc(1, 0);
|
||||
if (empty1 == NULL && empty2 == NULL) {
|
||||
if (verbose) {
|
||||
mbedtls_printf(" CALLOC(1,0): passed (NULL)\n");
|
||||
}
|
||||
} else if (empty1 == NULL || empty2 == NULL) {
|
||||
if (verbose) {
|
||||
mbedtls_printf(" CALLOC(1,0): failed (mix of NULL and non-NULL)\n");
|
||||
}
|
||||
++failures;
|
||||
} else if (empty1 == empty2) {
|
||||
if (verbose) {
|
||||
mbedtls_printf(" CALLOC(1,0): passed (same non-null)\n");
|
||||
}
|
||||
} else {
|
||||
if (verbose) {
|
||||
mbedtls_printf(" CALLOC(1,0): passed (distinct non-null)\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,6 +150,28 @@ static int calloc_self_test(int verbose)
|
|||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < buffer_3_size; i++) {
|
||||
if (buffer3[i] != 0) {
|
||||
++failures;
|
||||
if (verbose) {
|
||||
mbedtls_printf(" CALLOC(%u): failed (memory not initialized to 0)\n",
|
||||
buffer_3_size);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < buffer_4_size; i++) {
|
||||
if (buffer4[i] != 0) {
|
||||
++failures;
|
||||
if (verbose) {
|
||||
mbedtls_printf(" CALLOC(%u): failed (memory not initialized to 0)\n",
|
||||
buffer_4_size);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
mbedtls_printf("\n");
|
||||
}
|
||||
|
@ -129,6 +179,8 @@ static int calloc_self_test(int verbose)
|
|||
mbedtls_free(empty2);
|
||||
mbedtls_free(buffer1);
|
||||
mbedtls_free(buffer2);
|
||||
mbedtls_free(buffer3);
|
||||
mbedtls_free(buffer4);
|
||||
return failures;
|
||||
}
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
|
|
@ -192,6 +192,10 @@ pre_initialize_variables () {
|
|||
# default to -O2, use -Ox _after_ this if you want another level
|
||||
ASAN_CFLAGS='-O2 -Werror -fsanitize=address,undefined -fno-sanitize-recover=all'
|
||||
|
||||
# Platform tests have an allocation that returns null
|
||||
export ASAN_OPTIONS="allocator_may_return_null=1"
|
||||
export MSAN_OPTIONS="allocator_may_return_null=1"
|
||||
|
||||
# Gather the list of available components. These are the functions
|
||||
# defined in this script whose name starts with "component_".
|
||||
ALL_COMPONENTS=$(compgen -A function component_ | sed 's/component_//')
|
||||
|
|
|
@ -4,3 +4,6 @@ time_get_milliseconds:
|
|||
|
||||
Time: get seconds
|
||||
time_get_seconds:
|
||||
|
||||
Check mbedtls_calloc overallocation
|
||||
check_mbedtls_calloc_overallocation:SIZE_MAX/2:SIZE_MAX/2
|
||||
|
|
|
@ -120,3 +120,17 @@ void time_delay_seconds(int delay_secs)
|
|||
goto exit;
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void check_mbedtls_calloc_overallocation(intmax_t num, intmax_t size)
|
||||
{
|
||||
unsigned char *buf;
|
||||
buf = mbedtls_calloc((size_t) num, (size_t) size);
|
||||
/* Dummy usage of the pointer to prevent optimizing it */
|
||||
mbedtls_printf("calloc pointer : %p\n", buf);
|
||||
TEST_ASSERT(buf == NULL);
|
||||
|
||||
exit:
|
||||
mbedtls_free(buf);
|
||||
}
|
||||
/* END_CASE */
|
||||
|
|
Loading…
Reference in a new issue