Skip to content

Commit 8ee7d38

Browse files
author
gojimmypi
authored
Fix hash_test() memory leak in wolfcrypt/test/test.c (#8506)
* Fix hash_test() memory leak in wolfcrypt/test/test.c * Escape HASH_TYPE_E comparisons * Revised hash_test() in test.c * Use ERROR_OUT and WC_NO_ERR_TRACE patterns, polish * Remove placeholder init, no longer needed * remove verbose hash_test() WOLFSSL_MSG and PRINT_HEAP_CHECKPOINT
1 parent 704e97b commit 8ee7d38

4 files changed

Lines changed: 135 additions & 20 deletions

File tree

IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/include/user_settings.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -559,9 +559,6 @@
559559
defined(WOLFSSL_SP_RISCV32)
560560
#endif
561561

562-
#define WOLFSSL_SMALL_STACK
563-
564-
565562
#define HAVE_VERSION_EXTENDED_INFO
566563
/* #define HAVE_WC_INTROSPECTION */
567564

IDE/Espressif/ESP-IDF/examples/wolfssl_test/main/main.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ void app_main(void)
164164
.stop_bits = UART_STOP_BITS_1,
165165
};
166166
int stack_start = 0;
167+
int heap_start = 0;
168+
int heap_current = 0;
167169
int loops = 0;
168170
esp_err_t ret = 0;
169171

@@ -245,8 +247,12 @@ void app_main(void)
245247
** note it is still always called in wolf_test_task.
246248
*/
247249
stack_start = uxTaskGetStackHighWaterMark(NULL);
250+
heap_start = heap_caps_get_free_size(MALLOC_CAP_8BIT);
248251

249252
do {
253+
heap_current = heap_caps_get_free_size(MALLOC_CAP_8BIT);
254+
ESP_LOGI(TAG, "Free heap memory: %d bytes; Start %d",
255+
heap_current, heap_start);
250256
ESP_LOGI(TAG, "Stack HWM: %d\n", uxTaskGetStackHighWaterMark(NULL));
251257

252258
ret = wolf_test_task();
@@ -272,7 +278,7 @@ void app_main(void)
272278
ESP_LOGI(TAG, "Stack HWM: %d\n", uxTaskGetStackHighWaterMark(NULL));
273279
#endif
274280

275-
#if defined(DEBUG_WOLFSSL) && defined(WOLFSSL_ESP32_CRYPT_RSA_PRI)
281+
#if defined(WOLFSSL_HW_METRICS) && defined(WOLFSSL_ESP32_CRYPT_RSA_PRI)
276282
esp_hw_show_mp_metrics();
277283
#endif
278284

wolfcrypt/test/test.c

Lines changed: 122 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ const byte const_byte_array[] = "A+Gd\0\0\0";
9292
#else
9393
static ssize_t max_relative_heap_bytes = -1;
9494
#endif
95-
#define PRINT_HEAP_CHECKPOINT() { \
95+
96+
/* Optional breadcrumb string (b), and interaction, (i) not implemented */
97+
#define PRINT_HEAP_CHECKPOINT(b, i) { \
9698
const ssize_t _rha = wolfCrypt_heap_peakAllocs_checkpoint() - heap_baselineAllocs; \
9799
const ssize_t _rhb = wolfCrypt_heap_peakBytes_checkpoint() - heap_baselineBytes; \
98100
printf(" relative heap peak usage: %ld alloc%s, %ld bytes\n", \
@@ -109,9 +111,54 @@ const byte const_byte_array[] = "A+Gd\0\0\0";
109111
heap_baselineBytes = wolfCrypt_heap_peakBytes_checkpoint(); \
110112
}
111113
#else
112-
#define PRINT_HEAP_CHECKPOINT() WC_DO_NOTHING
114+
#define PRINT_HEAP_CHECKPOINT(b, i) WC_DO_NOTHING;
115+
#define PRINT_HEAP_ADDRESS(p) WC_DO_NOTHING;
113116
#endif /* WOLFSSL_TRACK_MEMORY_VERBOSE && !WOLFSSL_STATIC_MEMORY */
114117

118+
#ifdef WOLFSSL_ESPIDF
119+
#undef PRINT_HEAP_CHECKPOINT
120+
#undef PRINT_HEAP_ADDRESS
121+
static int esp_start_heap = 0;
122+
static int esp_last_heap = 0;
123+
static int esp_this_heap = 0;
124+
125+
#ifdef DEBUG_WOLFSSL_ESP32_HEAP
126+
#define PRINT_HEAP_CHECKPOINT(b, i) \
127+
esp_last_heap = esp_this_heap; \
128+
esp_this_heap = (int)heap_caps_get_free_size(MALLOC_CAP_8BIT); \
129+
if (esp_start_heap == 0) { \
130+
esp_start_heap = esp_this_heap; \
131+
} \
132+
ESP_LOGI(ESPIDF_TAG, "%s #%d; Heap free: %d", \
133+
((b) ? (b) : ""), /* breadcumb string */ \
134+
((i) ? (i) : 0), /* index */ \
135+
esp_this_heap);
136+
137+
#define PRINT_HEAP_ADDRESS(p) \
138+
ESP_LOGI(ESPIDF_TAG, "Allocated address: %p", (void *)(p));
139+
#else
140+
/* Even without verbose heap, we'll warn on anomalous values */
141+
#define PRINT_HEAP_CHECKPOINT(b, i) \
142+
esp_last_heap = esp_this_heap; \
143+
esp_this_heap = (int)heap_caps_get_free_size(MALLOC_CAP_8BIT); \
144+
if (esp_start_heap == 0) { \
145+
esp_start_heap = esp_this_heap; \
146+
esp_last_heap = esp_this_heap; \
147+
} \
148+
if (esp_this_heap == esp_last_heap) { \
149+
ESP_LOGV(ESPIDF_TAG, "Heap constant: %d", esp_this_heap); \
150+
} \
151+
else { \
152+
ESP_LOGI(ESPIDF_TAG, "Breadcrumb: %s", ((b) ? (b) : "")); \
153+
ESP_LOGW(ESPIDF_TAG, "Warning: this heap %d != last %d", \
154+
esp_this_heap, esp_last_heap); \
155+
}
156+
157+
#define PRINT_HEAP_ADDRESS(p) WC_DO_NOTHING;
158+
#endif
159+
#endif /* WOLFSSL_ESPIDF */
160+
161+
115162
#ifdef USE_FLAT_TEST_H
116163
#ifdef HAVE_CONFIG_H
117164
#include "test_paths.h"
@@ -1415,7 +1462,7 @@ static WOLFSSL_TEST_SUBROUTINE wc_test_ret_t nist_sp80056c_kdf_test(void)
14151462
va_start(args, fmt);
14161463
STACK_SIZE_CHECKPOINT_WITH_MAX_CHECK(max_relative_stack, vprintf(fmt, args));
14171464
va_end(args);
1418-
PRINT_HEAP_CHECKPOINT();
1465+
PRINT_HEAP_CHECKPOINT("",0);
14191466
TEST_SLEEP();
14201467
ASSERT_RESTORED_VECTOR_REGISTERS(exit(1););
14211468
}
@@ -1429,7 +1476,7 @@ static WOLFSSL_TEST_SUBROUTINE wc_test_ret_t nist_sp80056c_kdf_test(void)
14291476
(max_relative_stack, printf(__VA_ARGS__)) < 0) { \
14301477
return err_sys("post-test check failed", WC_TEST_RET_ENC_NC);\
14311478
} \
1432-
PRINT_HEAP_CHECKPOINT(); \
1479+
PRINT_HEAP_CHECKPOINT("TEST_PASS", 0) \
14331480
ASSERT_RESTORED_VECTOR_REGISTERS(exit(1);); \
14341481
}
14351482
#endif
@@ -6156,6 +6203,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hash_test(void)
61566203
#else
61576204
wc_HashAlg hash[1];
61586205
#endif
6206+
61596207
int ret, exp_ret;
61606208
int i, j;
61616209
int digestSz;
@@ -6216,7 +6264,10 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hash_test(void)
62166264
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
62176265
hash = wc_HashNew(WC_HASH_TYPE_SHA256, HEAP_HINT, devId, &ret);
62186266
if (hash == NULL) {
6219-
return WC_TEST_RET_ENC_EC(ret);
6267+
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
6268+
}
6269+
else {
6270+
PRINT_HEAP_ADDRESS(hash);
62206271
}
62216272
#else
62226273
XMEMSET(hash, 0, sizeof(wc_HashAlg));
@@ -6245,9 +6296,23 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hash_test(void)
62456296
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
62466297
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
62476298

6299+
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
6300+
/* Delete the WC_HASH_TYPE_SHA256 type hash for the following tests */
6301+
ret = wc_HashDelete(hash, &hash);
6302+
if (ret != 0)
6303+
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
6304+
#endif
6305+
62486306
/* Try invalid hash algorithms. */
62496307
for (i = 0; i < (int)(sizeof(typesBad)/sizeof(*typesBad)); i++) {
6308+
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
6309+
hash = wc_HashNew(typesBad[i], HEAP_HINT, devId, &ret);
6310+
#endif
6311+
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) {
6312+
ERROR_OUT(WC_TEST_RET_ENC_I(i), out);
6313+
}
62506314
ret = wc_HashInit(hash, typesBad[i]);
6315+
62516316
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
62526317
ERROR_OUT(WC_TEST_RET_ENC_I(i), out);
62536318
ret = wc_HashUpdate(hash, typesBad[i], data, sizeof(data));
@@ -6256,17 +6321,51 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hash_test(void)
62566321
ret = wc_HashFinal(hash, typesBad[i], out);
62576322
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
62586323
ERROR_OUT(WC_TEST_RET_ENC_I(i), out);
6259-
wc_HashFree(hash, typesBad[i]);
6324+
ret = wc_HashFree(hash, typesBad[i]);
6325+
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
6326+
ERROR_OUT(WC_TEST_RET_ENC_I(i), out);
6327+
6328+
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
6329+
ret = wc_HashDelete(hash, &hash);
6330+
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) {
6331+
WOLFSSL_MSG("ERROR: wc_HashDelete failed, expected BAD_FUNC_ARG.");
6332+
ERROR_OUT(WC_TEST_RET_ENC_I(i), out);
6333+
}
6334+
#endif
62606335
}
62616336

62626337
/* Try valid hash algorithms. */
6263-
for (i = 0, j = 0; i < (int)(sizeof(typesGood)/sizeof(*typesGood)); i++) {
6264-
exp_ret = 0;
6265-
if (typesGood[i] == typesNoImpl[j]) {
6266-
/* Recognized but no implementation compiled in. */
6267-
exp_ret = HASH_TYPE_E;
6268-
j++;
6338+
for (i = 0; i < (int)(sizeof(typesGood)/sizeof(*typesGood)); i++) {
6339+
exp_ret = 0; /* For valid had, we expect return result to be zero */
6340+
6341+
/* See if the current hash type is one of the known types that are
6342+
* not implemented or not compiled in (disabled): */
6343+
for(j = 0; j < (int)(sizeof(typesNoImpl) / sizeof(*typesNoImpl)); j++) {
6344+
if (typesGood[i] == typesNoImpl[j]) {
6345+
exp_ret = HASH_TYPE_E;
6346+
break; /* found one. don't keep looking.
6347+
* we won't test hashes not implemented */
6348+
}
6349+
}
6350+
6351+
/* If the expected return value is HASH_TYPE_E before we've even started
6352+
* it must be a hash type not implemented or disabled, so skip it. */
6353+
if (exp_ret == WC_NO_ERR_TRACE(HASH_TYPE_E)) {
6354+
continue; /* go fetch the next typesGood[i] */
62696355
}
6356+
6357+
/* Good type and implemented: */
6358+
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
6359+
hash = wc_HashNew(typesGood[i], HEAP_HINT, devId, &ret);
6360+
if (hash == NULL) {
6361+
WOLFSSL_MSG("ERROR: wc_HashNew failed.");
6362+
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
6363+
}
6364+
6365+
if (ret != 0) {
6366+
ERROR_OUT(WC_TEST_RET_ENC_I(BAD_FUNC_ARG), out);
6367+
}
6368+
#endif
62706369
ret = wc_HashInit(hash, typesGood[i]);
62716370
if (ret != exp_ret)
62726371
ERROR_OUT(WC_TEST_RET_ENC_I(i), out);
@@ -6313,8 +6412,18 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hash_test(void)
63136412
if (exp_ret == 0 && hashType != typesGood[i])
63146413
ERROR_OUT(WC_TEST_RET_ENC_I(i), out);
63156414
#endif /* !defined(NO_ASN) || !defined(NO_DH) || defined(HAVE_ECC) */
6316-
}
63176415

6416+
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
6417+
ret = wc_HashDelete(hash, &hash);
6418+
if (ret < 0) {
6419+
WOLFSSL_MSG("ERROR: Failed to delete hash.");
6420+
ERROR_OUT(WC_TEST_RET_ENC_I(i), out);
6421+
}
6422+
#endif
6423+
} /* Valid hash functions */
6424+
6425+
6426+
/* non wc_HashAlg hash object tests follow: */
63186427
for (i = 0; i < (int)(sizeof(typesHashBad)/sizeof(*typesHashBad)); i++) {
63196428
ret = wc_Hash(typesHashBad[i], data, sizeof(data), out, sizeof(out));
63206429
if ((ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) &&

wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,11 @@ enum {
216216
** Turns on diagnostic messages for SHA mutex. Note that given verbosity,
217217
** there may be TLS timing issues encountered. Use with caution.
218218
**
219+
** DEBUG_WOLFSSL_ESP32_HEAP
220+
** Prints heap memory usage
221+
**
219222
** DEBUG_WOLFSSL_ESP32_UNFINISHED_HW
220-
** This may be interesting in that HW may have been unnessearily locked
223+
** This may be interesting in that HW may have been unnecessarily locked
221224
** for hash that was never completed. (typically encountered at `free1` time)
222225
**
223226
** LOG_LOCAL_LEVEL
@@ -234,11 +237,11 @@ enum {
234237
** Shows a warning when mulm falls back for minimum number of bits.
235238
**
236239
** WOLFSSL_DEBUG_ESP_HW_MULTI_RSAMAX_BITS
237-
** Shows a marning when multiplication math bits have exceeded hardware
240+
** Shows a warning when multiplication math bits have exceeded hardware
238241
** capabilities and will fall back to slower software.
239242
**
240243
** WOLFSSL_DEBUG_ESP_HW_MOD_RSAMAX_BITS
241-
** Shows a marning when modular math bits have exceeded hardware capabilities
244+
** Shows a warning when modular math bits have exceeded hardware capabilities
242245
** and will fall back to slower software.
243246
**
244247
** NO_HW_MATH_TEST

0 commit comments

Comments
 (0)