1 /**
2  * \file memory.h
3  *
4  * \brief   Helper macros and functions related to testing memory management.
5  */
6 
7 /*
8  *  Copyright The Mbed TLS Contributors
9  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
10  */
11 
12 #ifndef TEST_MEMORY_H
13 #define TEST_MEMORY_H
14 
15 #include "mbedtls/build_info.h"
16 #include "mbedtls/platform.h"
17 #include "test/helpers.h"
18 
19 /** \def MBEDTLS_TEST_MEMORY_CAN_POISON
20  *
21  * This macro is defined if the tests are compiled with a method to mark
22  * memory as poisoned, which can be used to enforce some memory access
23  * policies.
24  *
25  * Support for the C11 thread_local keyword is also required.
26  *
27  * Currently, only Asan (Address Sanitizer) is supported.
28  */
29 #if defined(MBEDTLS_TEST_HAVE_ASAN) && \
30     (__STDC_VERSION__ >= 201112L) && \
31     !defined(PSA_CRYPTO_DRIVER_TEST)
32 #  define MBEDTLS_TEST_MEMORY_CAN_POISON
33 #endif
34 
35 /** \def MBEDTLS_TEST_MEMORY_POISON(buf, size)
36  *
37  * Poison a memory area so that any attempt to read or write from it will
38  * cause a runtime failure.
39  *
40  * Depending on the implementation, this may poison a few bytes beyond the
41  * indicated region, but will never poison a separate object on the heap
42  * or a separate object with more than the alignment of a long long.
43  *
44  * The behavior is undefined if any part of the memory area is invalid.
45  *
46  * This is a no-op in builds without a poisoning method.
47  * See #MBEDTLS_TEST_MEMORY_CAN_POISON.
48  *
49  * \param buf   Pointer to the beginning of the memory area to poison.
50  * \param size  Size of the memory area in bytes.
51  */
52 
53 /** \def MBEDTLS_TEST_MEMORY_UNPOISON(buf, size)
54  *
55  * Undo the effect of #MBEDTLS_TEST_MEMORY_POISON.
56  *
57  * The behavior is undefined if any part of the memory area is invalid,
58  * or if the memory area contains a mixture of poisoned and unpoisoned parts.
59  *
60  * This is a no-op in builds without a poisoning method.
61  * See #MBEDTLS_TEST_MEMORY_CAN_POISON.
62  *
63  * \param buf   Pointer to the beginning of the memory area to unpoison.
64  * \param size  Size of the memory area in bytes.
65  */
66 
67 #if defined(MBEDTLS_TEST_MEMORY_CAN_POISON)
68 
69 /** Thread-local variable used to enable memory poisoning. This is set and
70  *  unset in the test wrappers so that calls to PSA functions from the library
71  *  do not poison memory.
72  */
73 extern _Thread_local unsigned int mbedtls_test_memory_poisoning_count;
74 
75 /** Poison a memory area so that any attempt to read or write from it will
76  * cause a runtime failure.
77  *
78  * The behavior is undefined if any part of the memory area is invalid.
79  */
80 void mbedtls_test_memory_poison(const unsigned char *ptr, size_t size);
81 #define MBEDTLS_TEST_MEMORY_POISON(ptr, size)    \
82     do { \
83         mbedtls_test_memory_poisoning_count++; \
84         mbedtls_test_memory_poison(ptr, size); \
85     } while (0)
86 
87 /** Undo the effect of mbedtls_test_memory_poison().
88  *
89  * This is a no-op if the given area is entirely valid, unpoisoned memory.
90  *
91  * The behavior is undefined if any part of the memory area is invalid,
92  * or if the memory area contains a mixture of poisoned and unpoisoned parts.
93  */
94 void mbedtls_test_memory_unpoison(const unsigned char *ptr, size_t size);
95 #define MBEDTLS_TEST_MEMORY_UNPOISON(ptr, size)    \
96     do { \
97         mbedtls_test_memory_unpoison(ptr, size); \
98         if (mbedtls_test_memory_poisoning_count != 0) { \
99             mbedtls_test_memory_poisoning_count--; \
100         } \
101     } while (0)
102 
103 #else /* MBEDTLS_TEST_MEMORY_CAN_POISON */
104 #define MBEDTLS_TEST_MEMORY_POISON(ptr, size) ((void) (ptr), (void) (size))
105 #define MBEDTLS_TEST_MEMORY_UNPOISON(ptr, size) ((void) (ptr), (void) (size))
106 #endif /* MBEDTLS_TEST_MEMORY_CAN_POISON */
107 
108 #endif /* TEST_MEMORY_H */
109