/* SPDX-License-Identifier: GPL-3.0-only */ #include #include #include #include #include #include typedef struct { void *p; size_t n; bool wipe; } allocation; static allocation allocations[64]; static unsigned live, calls, fail_at, wiped_frees; static size_t secret_size; static bool all_secret; static void *test_alloc(size_t n, bool clear) { if (++calls == fail_at) return NULL; void *p = clear ? calloc(1, n + 16) : malloc(n + 16); assert(p); if (!clear) memset(p, 0xa5, n); memset((unsigned char *)p + n, 0x7b, 16); for (unsigned i = 0; i < 64; ++i) if (!allocations[i].p) { allocations[i] = (allocation){p, n, all_secret || n == secret_size}; ++live; return p; } abort(); } static void test_free(void *p) { if (!p) return; for (unsigned i = 0; i < 64; ++i) if (allocations[i].p == p) { for (size_t j = 0; j < 16; ++j) assert(((unsigned char *)p)[allocations[i].n + j] == 0x7b); if (allocations[i].wipe) { for (size_t j = 0; j < allocations[i].n; ++j) assert(((unsigned char *)p)[j] == 0); ++wiped_frees; } memset(p, 0xdd, allocations[i].n); allocations[i].p = NULL; --live; free(p); return; } assert(!"double free or unowned allocation"); } static void mark_secret(void *p) { for (unsigned i = 0; i < 64; ++i) if (allocations[i].p == p) { allocations[i].wipe = true; return; } abort(); } #define malloc(n) test_alloc((n), false) #define calloc(n, s) test_alloc((n) * (s), true) #define free(p) test_free(p) #define ESP_LOGE(...) ((void)0) #define ESP_LOGD(...) ((void)0) #define ESP_LOGI(...) ((void)0) #define ESP_LOGW(...) ((void)0) #define ESP_OK 0 #define ESP_FAIL -1 #define ESP_ERR_NO_MEM -2 #define ESP_ERR_INVALID_ARG -3 #define ESP_ERR_INVALID_STATE -4 #define ESP_ERR_NOT_SUPPORTED -5 typedef int esp_err_t;