1a8e1175bSopenharmony_ci/* 2a8e1175bSopenharmony_ci * Buffer-based memory allocator 3a8e1175bSopenharmony_ci * 4a8e1175bSopenharmony_ci * Copyright The Mbed TLS Contributors 5a8e1175bSopenharmony_ci * SPDX-License-Identifier: Apache-2.0 6a8e1175bSopenharmony_ci * 7a8e1175bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); you may 8a8e1175bSopenharmony_ci * not use this file except in compliance with the License. 9a8e1175bSopenharmony_ci * You may obtain a copy of the License at 10a8e1175bSopenharmony_ci * 11a8e1175bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12a8e1175bSopenharmony_ci * 13a8e1175bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14a8e1175bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15a8e1175bSopenharmony_ci * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16a8e1175bSopenharmony_ci * See the License for the specific language governing permissions and 17a8e1175bSopenharmony_ci * limitations under the License. 18a8e1175bSopenharmony_ci */ 19a8e1175bSopenharmony_ci 20a8e1175bSopenharmony_ci#include "common.h" 21a8e1175bSopenharmony_ci 22a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) 23a8e1175bSopenharmony_ci#include "mbedtls/memory_buffer_alloc.h" 24a8e1175bSopenharmony_ci 25a8e1175bSopenharmony_ci/* No need for the header guard as MBEDTLS_MEMORY_BUFFER_ALLOC_C 26a8e1175bSopenharmony_ci is dependent upon MBEDTLS_PLATFORM_C */ 27a8e1175bSopenharmony_ci#include "mbedtls/platform.h" 28a8e1175bSopenharmony_ci#include "mbedtls/platform_util.h" 29a8e1175bSopenharmony_ci 30a8e1175bSopenharmony_ci#include <string.h> 31a8e1175bSopenharmony_ci 32a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_BACKTRACE) 33a8e1175bSopenharmony_ci#include <execinfo.h> 34a8e1175bSopenharmony_ci#endif 35a8e1175bSopenharmony_ci 36a8e1175bSopenharmony_ci#if defined(MBEDTLS_THREADING_C) 37a8e1175bSopenharmony_ci#include "mbedtls/threading.h" 38a8e1175bSopenharmony_ci#endif 39a8e1175bSopenharmony_ci 40a8e1175bSopenharmony_ci#define MAGIC1 0xFF00AA55 41a8e1175bSopenharmony_ci#define MAGIC2 0xEE119966 42a8e1175bSopenharmony_ci#define MAX_BT 20 43a8e1175bSopenharmony_ci 44a8e1175bSopenharmony_citypedef struct _memory_header memory_header; 45a8e1175bSopenharmony_cistruct _memory_header { 46a8e1175bSopenharmony_ci size_t magic1; 47a8e1175bSopenharmony_ci size_t size; 48a8e1175bSopenharmony_ci size_t alloc; 49a8e1175bSopenharmony_ci memory_header *prev; 50a8e1175bSopenharmony_ci memory_header *next; 51a8e1175bSopenharmony_ci memory_header *prev_free; 52a8e1175bSopenharmony_ci memory_header *next_free; 53a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_BACKTRACE) 54a8e1175bSopenharmony_ci char **trace; 55a8e1175bSopenharmony_ci size_t trace_count; 56a8e1175bSopenharmony_ci#endif 57a8e1175bSopenharmony_ci size_t magic2; 58a8e1175bSopenharmony_ci}; 59a8e1175bSopenharmony_ci 60a8e1175bSopenharmony_citypedef struct { 61a8e1175bSopenharmony_ci unsigned char *buf; 62a8e1175bSopenharmony_ci size_t len; 63a8e1175bSopenharmony_ci memory_header *first; 64a8e1175bSopenharmony_ci memory_header *first_free; 65a8e1175bSopenharmony_ci int verify; 66a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG) 67a8e1175bSopenharmony_ci size_t alloc_count; 68a8e1175bSopenharmony_ci size_t free_count; 69a8e1175bSopenharmony_ci size_t total_used; 70a8e1175bSopenharmony_ci size_t maximum_used; 71a8e1175bSopenharmony_ci size_t header_count; 72a8e1175bSopenharmony_ci size_t maximum_header_count; 73a8e1175bSopenharmony_ci#endif 74a8e1175bSopenharmony_ci#if defined(MBEDTLS_THREADING_C) 75a8e1175bSopenharmony_ci mbedtls_threading_mutex_t mutex; 76a8e1175bSopenharmony_ci#endif 77a8e1175bSopenharmony_ci} 78a8e1175bSopenharmony_cibuffer_alloc_ctx; 79a8e1175bSopenharmony_ci 80a8e1175bSopenharmony_cistatic buffer_alloc_ctx heap; 81a8e1175bSopenharmony_ci 82a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG) 83a8e1175bSopenharmony_cistatic void debug_header(memory_header *hdr) 84a8e1175bSopenharmony_ci{ 85a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_BACKTRACE) 86a8e1175bSopenharmony_ci size_t i; 87a8e1175bSopenharmony_ci#endif 88a8e1175bSopenharmony_ci 89a8e1175bSopenharmony_ci mbedtls_fprintf(stderr, "HDR: PTR(%10zu), PREV(%10zu), NEXT(%10zu), " 90a8e1175bSopenharmony_ci "ALLOC(%zu), SIZE(%10zu)\n", 91a8e1175bSopenharmony_ci (size_t) hdr, (size_t) hdr->prev, (size_t) hdr->next, 92a8e1175bSopenharmony_ci hdr->alloc, hdr->size); 93a8e1175bSopenharmony_ci mbedtls_fprintf(stderr, " FPREV(%10zu), FNEXT(%10zu)\n", 94a8e1175bSopenharmony_ci (size_t) hdr->prev_free, (size_t) hdr->next_free); 95a8e1175bSopenharmony_ci 96a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_BACKTRACE) 97a8e1175bSopenharmony_ci mbedtls_fprintf(stderr, "TRACE: \n"); 98a8e1175bSopenharmony_ci for (i = 0; i < hdr->trace_count; i++) { 99a8e1175bSopenharmony_ci mbedtls_fprintf(stderr, "%s\n", hdr->trace[i]); 100a8e1175bSopenharmony_ci } 101a8e1175bSopenharmony_ci mbedtls_fprintf(stderr, "\n"); 102a8e1175bSopenharmony_ci#endif 103a8e1175bSopenharmony_ci} 104a8e1175bSopenharmony_ci 105a8e1175bSopenharmony_cistatic void debug_chain(void) 106a8e1175bSopenharmony_ci{ 107a8e1175bSopenharmony_ci memory_header *cur = heap.first; 108a8e1175bSopenharmony_ci 109a8e1175bSopenharmony_ci mbedtls_fprintf(stderr, "\nBlock list\n"); 110a8e1175bSopenharmony_ci while (cur != NULL) { 111a8e1175bSopenharmony_ci debug_header(cur); 112a8e1175bSopenharmony_ci cur = cur->next; 113a8e1175bSopenharmony_ci } 114a8e1175bSopenharmony_ci 115a8e1175bSopenharmony_ci mbedtls_fprintf(stderr, "Free list\n"); 116a8e1175bSopenharmony_ci cur = heap.first_free; 117a8e1175bSopenharmony_ci 118a8e1175bSopenharmony_ci while (cur != NULL) { 119a8e1175bSopenharmony_ci debug_header(cur); 120a8e1175bSopenharmony_ci cur = cur->next_free; 121a8e1175bSopenharmony_ci } 122a8e1175bSopenharmony_ci} 123a8e1175bSopenharmony_ci#endif /* MBEDTLS_MEMORY_DEBUG */ 124a8e1175bSopenharmony_ci 125a8e1175bSopenharmony_cistatic int verify_header(memory_header *hdr) 126a8e1175bSopenharmony_ci{ 127a8e1175bSopenharmony_ci if (hdr->magic1 != MAGIC1) { 128a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG) 129a8e1175bSopenharmony_ci mbedtls_fprintf(stderr, "FATAL: MAGIC1 mismatch\n"); 130a8e1175bSopenharmony_ci#endif 131a8e1175bSopenharmony_ci return 1; 132a8e1175bSopenharmony_ci } 133a8e1175bSopenharmony_ci 134a8e1175bSopenharmony_ci if (hdr->magic2 != MAGIC2) { 135a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG) 136a8e1175bSopenharmony_ci mbedtls_fprintf(stderr, "FATAL: MAGIC2 mismatch\n"); 137a8e1175bSopenharmony_ci#endif 138a8e1175bSopenharmony_ci return 1; 139a8e1175bSopenharmony_ci } 140a8e1175bSopenharmony_ci 141a8e1175bSopenharmony_ci if (hdr->alloc > 1) { 142a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG) 143a8e1175bSopenharmony_ci mbedtls_fprintf(stderr, "FATAL: alloc has illegal value\n"); 144a8e1175bSopenharmony_ci#endif 145a8e1175bSopenharmony_ci return 1; 146a8e1175bSopenharmony_ci } 147a8e1175bSopenharmony_ci 148a8e1175bSopenharmony_ci if (hdr->prev != NULL && hdr->prev == hdr->next) { 149a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG) 150a8e1175bSopenharmony_ci mbedtls_fprintf(stderr, "FATAL: prev == next\n"); 151a8e1175bSopenharmony_ci#endif 152a8e1175bSopenharmony_ci return 1; 153a8e1175bSopenharmony_ci } 154a8e1175bSopenharmony_ci 155a8e1175bSopenharmony_ci if (hdr->prev_free != NULL && hdr->prev_free == hdr->next_free) { 156a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG) 157a8e1175bSopenharmony_ci mbedtls_fprintf(stderr, "FATAL: prev_free == next_free\n"); 158a8e1175bSopenharmony_ci#endif 159a8e1175bSopenharmony_ci return 1; 160a8e1175bSopenharmony_ci } 161a8e1175bSopenharmony_ci 162a8e1175bSopenharmony_ci return 0; 163a8e1175bSopenharmony_ci} 164a8e1175bSopenharmony_ci 165a8e1175bSopenharmony_cistatic int verify_chain(void) 166a8e1175bSopenharmony_ci{ 167a8e1175bSopenharmony_ci memory_header *prv = heap.first, *cur; 168a8e1175bSopenharmony_ci 169a8e1175bSopenharmony_ci if (prv == NULL || verify_header(prv) != 0) { 170a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG) 171a8e1175bSopenharmony_ci mbedtls_fprintf(stderr, "FATAL: verification of first header " 172a8e1175bSopenharmony_ci "failed\n"); 173a8e1175bSopenharmony_ci#endif 174a8e1175bSopenharmony_ci return 1; 175a8e1175bSopenharmony_ci } 176a8e1175bSopenharmony_ci 177a8e1175bSopenharmony_ci if (heap.first->prev != NULL) { 178a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG) 179a8e1175bSopenharmony_ci mbedtls_fprintf(stderr, "FATAL: verification failed: " 180a8e1175bSopenharmony_ci "first->prev != NULL\n"); 181a8e1175bSopenharmony_ci#endif 182a8e1175bSopenharmony_ci return 1; 183a8e1175bSopenharmony_ci } 184a8e1175bSopenharmony_ci 185a8e1175bSopenharmony_ci cur = heap.first->next; 186a8e1175bSopenharmony_ci 187a8e1175bSopenharmony_ci while (cur != NULL) { 188a8e1175bSopenharmony_ci if (verify_header(cur) != 0) { 189a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG) 190a8e1175bSopenharmony_ci mbedtls_fprintf(stderr, "FATAL: verification of header " 191a8e1175bSopenharmony_ci "failed\n"); 192a8e1175bSopenharmony_ci#endif 193a8e1175bSopenharmony_ci return 1; 194a8e1175bSopenharmony_ci } 195a8e1175bSopenharmony_ci 196a8e1175bSopenharmony_ci if (cur->prev != prv) { 197a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG) 198a8e1175bSopenharmony_ci mbedtls_fprintf(stderr, "FATAL: verification failed: " 199a8e1175bSopenharmony_ci "cur->prev != prv\n"); 200a8e1175bSopenharmony_ci#endif 201a8e1175bSopenharmony_ci return 1; 202a8e1175bSopenharmony_ci } 203a8e1175bSopenharmony_ci 204a8e1175bSopenharmony_ci prv = cur; 205a8e1175bSopenharmony_ci cur = cur->next; 206a8e1175bSopenharmony_ci } 207a8e1175bSopenharmony_ci 208a8e1175bSopenharmony_ci return 0; 209a8e1175bSopenharmony_ci} 210a8e1175bSopenharmony_ci 211a8e1175bSopenharmony_cistatic void *buffer_alloc_calloc(size_t n, size_t size) 212a8e1175bSopenharmony_ci{ 213a8e1175bSopenharmony_ci memory_header *new, *cur = heap.first_free; 214a8e1175bSopenharmony_ci unsigned char *p; 215a8e1175bSopenharmony_ci void *ret; 216a8e1175bSopenharmony_ci size_t original_len, len; 217a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_BACKTRACE) 218a8e1175bSopenharmony_ci void *trace_buffer[MAX_BT]; 219a8e1175bSopenharmony_ci size_t trace_cnt; 220a8e1175bSopenharmony_ci#endif 221a8e1175bSopenharmony_ci 222a8e1175bSopenharmony_ci if (heap.buf == NULL || heap.first == NULL) { 223a8e1175bSopenharmony_ci return NULL; 224a8e1175bSopenharmony_ci } 225a8e1175bSopenharmony_ci 226a8e1175bSopenharmony_ci original_len = len = n * size; 227a8e1175bSopenharmony_ci 228a8e1175bSopenharmony_ci if (n == 0 || size == 0 || len / n != size) { 229a8e1175bSopenharmony_ci return NULL; 230a8e1175bSopenharmony_ci } else if (len > (size_t) -MBEDTLS_MEMORY_ALIGN_MULTIPLE) { 231a8e1175bSopenharmony_ci return NULL; 232a8e1175bSopenharmony_ci } 233a8e1175bSopenharmony_ci 234a8e1175bSopenharmony_ci if (len % MBEDTLS_MEMORY_ALIGN_MULTIPLE) { 235a8e1175bSopenharmony_ci len -= len % MBEDTLS_MEMORY_ALIGN_MULTIPLE; 236a8e1175bSopenharmony_ci len += MBEDTLS_MEMORY_ALIGN_MULTIPLE; 237a8e1175bSopenharmony_ci } 238a8e1175bSopenharmony_ci 239a8e1175bSopenharmony_ci // Find block that fits 240a8e1175bSopenharmony_ci // 241a8e1175bSopenharmony_ci while (cur != NULL) { 242a8e1175bSopenharmony_ci if (cur->size >= len) { 243a8e1175bSopenharmony_ci break; 244a8e1175bSopenharmony_ci } 245a8e1175bSopenharmony_ci 246a8e1175bSopenharmony_ci cur = cur->next_free; 247a8e1175bSopenharmony_ci } 248a8e1175bSopenharmony_ci 249a8e1175bSopenharmony_ci if (cur == NULL) { 250a8e1175bSopenharmony_ci return NULL; 251a8e1175bSopenharmony_ci } 252a8e1175bSopenharmony_ci 253a8e1175bSopenharmony_ci if (cur->alloc != 0) { 254a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG) 255a8e1175bSopenharmony_ci mbedtls_fprintf(stderr, "FATAL: block in free_list but allocated " 256a8e1175bSopenharmony_ci "data\n"); 257a8e1175bSopenharmony_ci#endif 258a8e1175bSopenharmony_ci mbedtls_exit(1); 259a8e1175bSopenharmony_ci } 260a8e1175bSopenharmony_ci 261a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG) 262a8e1175bSopenharmony_ci heap.alloc_count++; 263a8e1175bSopenharmony_ci#endif 264a8e1175bSopenharmony_ci 265a8e1175bSopenharmony_ci // Found location, split block if > memory_header + 4 room left 266a8e1175bSopenharmony_ci // 267a8e1175bSopenharmony_ci if (cur->size - len < sizeof(memory_header) + 268a8e1175bSopenharmony_ci MBEDTLS_MEMORY_ALIGN_MULTIPLE) { 269a8e1175bSopenharmony_ci cur->alloc = 1; 270a8e1175bSopenharmony_ci 271a8e1175bSopenharmony_ci // Remove from free_list 272a8e1175bSopenharmony_ci // 273a8e1175bSopenharmony_ci if (cur->prev_free != NULL) { 274a8e1175bSopenharmony_ci cur->prev_free->next_free = cur->next_free; 275a8e1175bSopenharmony_ci } else { 276a8e1175bSopenharmony_ci heap.first_free = cur->next_free; 277a8e1175bSopenharmony_ci } 278a8e1175bSopenharmony_ci 279a8e1175bSopenharmony_ci if (cur->next_free != NULL) { 280a8e1175bSopenharmony_ci cur->next_free->prev_free = cur->prev_free; 281a8e1175bSopenharmony_ci } 282a8e1175bSopenharmony_ci 283a8e1175bSopenharmony_ci cur->prev_free = NULL; 284a8e1175bSopenharmony_ci cur->next_free = NULL; 285a8e1175bSopenharmony_ci 286a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG) 287a8e1175bSopenharmony_ci heap.total_used += cur->size; 288a8e1175bSopenharmony_ci if (heap.total_used > heap.maximum_used) { 289a8e1175bSopenharmony_ci heap.maximum_used = heap.total_used; 290a8e1175bSopenharmony_ci } 291a8e1175bSopenharmony_ci#endif 292a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_BACKTRACE) 293a8e1175bSopenharmony_ci trace_cnt = backtrace(trace_buffer, MAX_BT); 294a8e1175bSopenharmony_ci cur->trace = backtrace_symbols(trace_buffer, trace_cnt); 295a8e1175bSopenharmony_ci cur->trace_count = trace_cnt; 296a8e1175bSopenharmony_ci#endif 297a8e1175bSopenharmony_ci 298a8e1175bSopenharmony_ci if ((heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC) && verify_chain() != 0) { 299a8e1175bSopenharmony_ci mbedtls_exit(1); 300a8e1175bSopenharmony_ci } 301a8e1175bSopenharmony_ci 302a8e1175bSopenharmony_ci ret = (unsigned char *) cur + sizeof(memory_header); 303a8e1175bSopenharmony_ci memset(ret, 0, original_len); 304a8e1175bSopenharmony_ci 305a8e1175bSopenharmony_ci return ret; 306a8e1175bSopenharmony_ci } 307a8e1175bSopenharmony_ci 308a8e1175bSopenharmony_ci p = ((unsigned char *) cur) + sizeof(memory_header) + len; 309a8e1175bSopenharmony_ci new = (memory_header *) p; 310a8e1175bSopenharmony_ci 311a8e1175bSopenharmony_ci new->size = cur->size - len - sizeof(memory_header); 312a8e1175bSopenharmony_ci new->alloc = 0; 313a8e1175bSopenharmony_ci new->prev = cur; 314a8e1175bSopenharmony_ci new->next = cur->next; 315a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_BACKTRACE) 316a8e1175bSopenharmony_ci new->trace = NULL; 317a8e1175bSopenharmony_ci new->trace_count = 0; 318a8e1175bSopenharmony_ci#endif 319a8e1175bSopenharmony_ci new->magic1 = MAGIC1; 320a8e1175bSopenharmony_ci new->magic2 = MAGIC2; 321a8e1175bSopenharmony_ci 322a8e1175bSopenharmony_ci if (new->next != NULL) { 323a8e1175bSopenharmony_ci new->next->prev = new; 324a8e1175bSopenharmony_ci } 325a8e1175bSopenharmony_ci 326a8e1175bSopenharmony_ci // Replace cur with new in free_list 327a8e1175bSopenharmony_ci // 328a8e1175bSopenharmony_ci new->prev_free = cur->prev_free; 329a8e1175bSopenharmony_ci new->next_free = cur->next_free; 330a8e1175bSopenharmony_ci if (new->prev_free != NULL) { 331a8e1175bSopenharmony_ci new->prev_free->next_free = new; 332a8e1175bSopenharmony_ci } else { 333a8e1175bSopenharmony_ci heap.first_free = new; 334a8e1175bSopenharmony_ci } 335a8e1175bSopenharmony_ci 336a8e1175bSopenharmony_ci if (new->next_free != NULL) { 337a8e1175bSopenharmony_ci new->next_free->prev_free = new; 338a8e1175bSopenharmony_ci } 339a8e1175bSopenharmony_ci 340a8e1175bSopenharmony_ci cur->alloc = 1; 341a8e1175bSopenharmony_ci cur->size = len; 342a8e1175bSopenharmony_ci cur->next = new; 343a8e1175bSopenharmony_ci cur->prev_free = NULL; 344a8e1175bSopenharmony_ci cur->next_free = NULL; 345a8e1175bSopenharmony_ci 346a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG) 347a8e1175bSopenharmony_ci heap.header_count++; 348a8e1175bSopenharmony_ci if (heap.header_count > heap.maximum_header_count) { 349a8e1175bSopenharmony_ci heap.maximum_header_count = heap.header_count; 350a8e1175bSopenharmony_ci } 351a8e1175bSopenharmony_ci heap.total_used += cur->size; 352a8e1175bSopenharmony_ci if (heap.total_used > heap.maximum_used) { 353a8e1175bSopenharmony_ci heap.maximum_used = heap.total_used; 354a8e1175bSopenharmony_ci } 355a8e1175bSopenharmony_ci#endif 356a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_BACKTRACE) 357a8e1175bSopenharmony_ci trace_cnt = backtrace(trace_buffer, MAX_BT); 358a8e1175bSopenharmony_ci cur->trace = backtrace_symbols(trace_buffer, trace_cnt); 359a8e1175bSopenharmony_ci cur->trace_count = trace_cnt; 360a8e1175bSopenharmony_ci#endif 361a8e1175bSopenharmony_ci 362a8e1175bSopenharmony_ci if ((heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC) && verify_chain() != 0) { 363a8e1175bSopenharmony_ci mbedtls_exit(1); 364a8e1175bSopenharmony_ci } 365a8e1175bSopenharmony_ci 366a8e1175bSopenharmony_ci ret = (unsigned char *) cur + sizeof(memory_header); 367a8e1175bSopenharmony_ci memset(ret, 0, original_len); 368a8e1175bSopenharmony_ci 369a8e1175bSopenharmony_ci return ret; 370a8e1175bSopenharmony_ci} 371a8e1175bSopenharmony_ci 372a8e1175bSopenharmony_cistatic void buffer_alloc_free(void *ptr) 373a8e1175bSopenharmony_ci{ 374a8e1175bSopenharmony_ci memory_header *hdr, *old = NULL; 375a8e1175bSopenharmony_ci unsigned char *p = (unsigned char *) ptr; 376a8e1175bSopenharmony_ci 377a8e1175bSopenharmony_ci if (ptr == NULL || heap.buf == NULL || heap.first == NULL) { 378a8e1175bSopenharmony_ci return; 379a8e1175bSopenharmony_ci } 380a8e1175bSopenharmony_ci 381a8e1175bSopenharmony_ci if (p < heap.buf || p >= heap.buf + heap.len) { 382a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG) 383a8e1175bSopenharmony_ci mbedtls_fprintf(stderr, "FATAL: mbedtls_free() outside of managed " 384a8e1175bSopenharmony_ci "space\n"); 385a8e1175bSopenharmony_ci#endif 386a8e1175bSopenharmony_ci mbedtls_exit(1); 387a8e1175bSopenharmony_ci } 388a8e1175bSopenharmony_ci 389a8e1175bSopenharmony_ci p -= sizeof(memory_header); 390a8e1175bSopenharmony_ci hdr = (memory_header *) p; 391a8e1175bSopenharmony_ci 392a8e1175bSopenharmony_ci if (verify_header(hdr) != 0) { 393a8e1175bSopenharmony_ci mbedtls_exit(1); 394a8e1175bSopenharmony_ci } 395a8e1175bSopenharmony_ci 396a8e1175bSopenharmony_ci if (hdr->alloc != 1) { 397a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG) 398a8e1175bSopenharmony_ci mbedtls_fprintf(stderr, "FATAL: mbedtls_free() on unallocated " 399a8e1175bSopenharmony_ci "data\n"); 400a8e1175bSopenharmony_ci#endif 401a8e1175bSopenharmony_ci mbedtls_exit(1); 402a8e1175bSopenharmony_ci } 403a8e1175bSopenharmony_ci 404a8e1175bSopenharmony_ci hdr->alloc = 0; 405a8e1175bSopenharmony_ci 406a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG) 407a8e1175bSopenharmony_ci heap.free_count++; 408a8e1175bSopenharmony_ci heap.total_used -= hdr->size; 409a8e1175bSopenharmony_ci#endif 410a8e1175bSopenharmony_ci 411a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_BACKTRACE) 412a8e1175bSopenharmony_ci free(hdr->trace); 413a8e1175bSopenharmony_ci hdr->trace = NULL; 414a8e1175bSopenharmony_ci hdr->trace_count = 0; 415a8e1175bSopenharmony_ci#endif 416a8e1175bSopenharmony_ci 417a8e1175bSopenharmony_ci // Regroup with block before 418a8e1175bSopenharmony_ci // 419a8e1175bSopenharmony_ci if (hdr->prev != NULL && hdr->prev->alloc == 0) { 420a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG) 421a8e1175bSopenharmony_ci heap.header_count--; 422a8e1175bSopenharmony_ci#endif 423a8e1175bSopenharmony_ci hdr->prev->size += sizeof(memory_header) + hdr->size; 424a8e1175bSopenharmony_ci hdr->prev->next = hdr->next; 425a8e1175bSopenharmony_ci old = hdr; 426a8e1175bSopenharmony_ci hdr = hdr->prev; 427a8e1175bSopenharmony_ci 428a8e1175bSopenharmony_ci if (hdr->next != NULL) { 429a8e1175bSopenharmony_ci hdr->next->prev = hdr; 430a8e1175bSopenharmony_ci } 431a8e1175bSopenharmony_ci 432a8e1175bSopenharmony_ci memset(old, 0, sizeof(memory_header)); 433a8e1175bSopenharmony_ci } 434a8e1175bSopenharmony_ci 435a8e1175bSopenharmony_ci // Regroup with block after 436a8e1175bSopenharmony_ci // 437a8e1175bSopenharmony_ci if (hdr->next != NULL && hdr->next->alloc == 0) { 438a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG) 439a8e1175bSopenharmony_ci heap.header_count--; 440a8e1175bSopenharmony_ci#endif 441a8e1175bSopenharmony_ci hdr->size += sizeof(memory_header) + hdr->next->size; 442a8e1175bSopenharmony_ci old = hdr->next; 443a8e1175bSopenharmony_ci hdr->next = hdr->next->next; 444a8e1175bSopenharmony_ci 445a8e1175bSopenharmony_ci if (hdr->prev_free != NULL || hdr->next_free != NULL) { 446a8e1175bSopenharmony_ci if (hdr->prev_free != NULL) { 447a8e1175bSopenharmony_ci hdr->prev_free->next_free = hdr->next_free; 448a8e1175bSopenharmony_ci } else { 449a8e1175bSopenharmony_ci heap.first_free = hdr->next_free; 450a8e1175bSopenharmony_ci } 451a8e1175bSopenharmony_ci 452a8e1175bSopenharmony_ci if (hdr->next_free != NULL) { 453a8e1175bSopenharmony_ci hdr->next_free->prev_free = hdr->prev_free; 454a8e1175bSopenharmony_ci } 455a8e1175bSopenharmony_ci } 456a8e1175bSopenharmony_ci 457a8e1175bSopenharmony_ci hdr->prev_free = old->prev_free; 458a8e1175bSopenharmony_ci hdr->next_free = old->next_free; 459a8e1175bSopenharmony_ci 460a8e1175bSopenharmony_ci if (hdr->prev_free != NULL) { 461a8e1175bSopenharmony_ci hdr->prev_free->next_free = hdr; 462a8e1175bSopenharmony_ci } else { 463a8e1175bSopenharmony_ci heap.first_free = hdr; 464a8e1175bSopenharmony_ci } 465a8e1175bSopenharmony_ci 466a8e1175bSopenharmony_ci if (hdr->next_free != NULL) { 467a8e1175bSopenharmony_ci hdr->next_free->prev_free = hdr; 468a8e1175bSopenharmony_ci } 469a8e1175bSopenharmony_ci 470a8e1175bSopenharmony_ci if (hdr->next != NULL) { 471a8e1175bSopenharmony_ci hdr->next->prev = hdr; 472a8e1175bSopenharmony_ci } 473a8e1175bSopenharmony_ci 474a8e1175bSopenharmony_ci memset(old, 0, sizeof(memory_header)); 475a8e1175bSopenharmony_ci } 476a8e1175bSopenharmony_ci 477a8e1175bSopenharmony_ci // Prepend to free_list if we have not merged 478a8e1175bSopenharmony_ci // (Does not have to stay in same order as prev / next list) 479a8e1175bSopenharmony_ci // 480a8e1175bSopenharmony_ci if (old == NULL) { 481a8e1175bSopenharmony_ci hdr->next_free = heap.first_free; 482a8e1175bSopenharmony_ci if (heap.first_free != NULL) { 483a8e1175bSopenharmony_ci heap.first_free->prev_free = hdr; 484a8e1175bSopenharmony_ci } 485a8e1175bSopenharmony_ci heap.first_free = hdr; 486a8e1175bSopenharmony_ci } 487a8e1175bSopenharmony_ci 488a8e1175bSopenharmony_ci if ((heap.verify & MBEDTLS_MEMORY_VERIFY_FREE) && verify_chain() != 0) { 489a8e1175bSopenharmony_ci mbedtls_exit(1); 490a8e1175bSopenharmony_ci } 491a8e1175bSopenharmony_ci} 492a8e1175bSopenharmony_ci 493a8e1175bSopenharmony_civoid mbedtls_memory_buffer_set_verify(int verify) 494a8e1175bSopenharmony_ci{ 495a8e1175bSopenharmony_ci heap.verify = verify; 496a8e1175bSopenharmony_ci} 497a8e1175bSopenharmony_ci 498a8e1175bSopenharmony_ciint mbedtls_memory_buffer_alloc_verify(void) 499a8e1175bSopenharmony_ci{ 500a8e1175bSopenharmony_ci return verify_chain(); 501a8e1175bSopenharmony_ci} 502a8e1175bSopenharmony_ci 503a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG) 504a8e1175bSopenharmony_civoid mbedtls_memory_buffer_alloc_status(void) 505a8e1175bSopenharmony_ci{ 506a8e1175bSopenharmony_ci mbedtls_fprintf(stderr, 507a8e1175bSopenharmony_ci "Current use: %zu blocks / %zu bytes, max: %zu blocks / " 508a8e1175bSopenharmony_ci "%zu bytes (total %zu bytes), alloc / free: %zu / %zu\n", 509a8e1175bSopenharmony_ci heap.header_count, heap.total_used, 510a8e1175bSopenharmony_ci heap.maximum_header_count, heap.maximum_used, 511a8e1175bSopenharmony_ci heap.maximum_header_count * sizeof(memory_header) 512a8e1175bSopenharmony_ci + heap.maximum_used, 513a8e1175bSopenharmony_ci heap.alloc_count, heap.free_count); 514a8e1175bSopenharmony_ci 515a8e1175bSopenharmony_ci if (heap.first->next == NULL) { 516a8e1175bSopenharmony_ci mbedtls_fprintf(stderr, "All memory de-allocated in stack buffer\n"); 517a8e1175bSopenharmony_ci } else { 518a8e1175bSopenharmony_ci mbedtls_fprintf(stderr, "Memory currently allocated:\n"); 519a8e1175bSopenharmony_ci debug_chain(); 520a8e1175bSopenharmony_ci } 521a8e1175bSopenharmony_ci} 522a8e1175bSopenharmony_ci 523a8e1175bSopenharmony_civoid mbedtls_memory_buffer_alloc_count_get(size_t *alloc_count, size_t *free_count) 524a8e1175bSopenharmony_ci{ 525a8e1175bSopenharmony_ci *alloc_count = heap.alloc_count; 526a8e1175bSopenharmony_ci *free_count = heap.free_count; 527a8e1175bSopenharmony_ci} 528a8e1175bSopenharmony_ci 529a8e1175bSopenharmony_civoid mbedtls_memory_buffer_alloc_max_get(size_t *max_used, size_t *max_blocks) 530a8e1175bSopenharmony_ci{ 531a8e1175bSopenharmony_ci *max_used = heap.maximum_used; 532a8e1175bSopenharmony_ci *max_blocks = heap.maximum_header_count; 533a8e1175bSopenharmony_ci} 534a8e1175bSopenharmony_ci 535a8e1175bSopenharmony_civoid mbedtls_memory_buffer_alloc_max_reset(void) 536a8e1175bSopenharmony_ci{ 537a8e1175bSopenharmony_ci heap.maximum_used = 0; 538a8e1175bSopenharmony_ci heap.maximum_header_count = 0; 539a8e1175bSopenharmony_ci} 540a8e1175bSopenharmony_ci 541a8e1175bSopenharmony_civoid mbedtls_memory_buffer_alloc_cur_get(size_t *cur_used, size_t *cur_blocks) 542a8e1175bSopenharmony_ci{ 543a8e1175bSopenharmony_ci *cur_used = heap.total_used; 544a8e1175bSopenharmony_ci *cur_blocks = heap.header_count; 545a8e1175bSopenharmony_ci} 546a8e1175bSopenharmony_ci#endif /* MBEDTLS_MEMORY_DEBUG */ 547a8e1175bSopenharmony_ci 548a8e1175bSopenharmony_ci#if defined(MBEDTLS_THREADING_C) 549a8e1175bSopenharmony_cistatic void *buffer_alloc_calloc_mutexed(size_t n, size_t size) 550a8e1175bSopenharmony_ci{ 551a8e1175bSopenharmony_ci void *buf; 552a8e1175bSopenharmony_ci if (mbedtls_mutex_lock(&heap.mutex) != 0) { 553a8e1175bSopenharmony_ci return NULL; 554a8e1175bSopenharmony_ci } 555a8e1175bSopenharmony_ci buf = buffer_alloc_calloc(n, size); 556a8e1175bSopenharmony_ci if (mbedtls_mutex_unlock(&heap.mutex)) { 557a8e1175bSopenharmony_ci return NULL; 558a8e1175bSopenharmony_ci } 559a8e1175bSopenharmony_ci return buf; 560a8e1175bSopenharmony_ci} 561a8e1175bSopenharmony_ci 562a8e1175bSopenharmony_cistatic void buffer_alloc_free_mutexed(void *ptr) 563a8e1175bSopenharmony_ci{ 564a8e1175bSopenharmony_ci /* We have no good option here, but corrupting the heap seems 565a8e1175bSopenharmony_ci * worse than losing memory. */ 566a8e1175bSopenharmony_ci if (mbedtls_mutex_lock(&heap.mutex)) { 567a8e1175bSopenharmony_ci return; 568a8e1175bSopenharmony_ci } 569a8e1175bSopenharmony_ci buffer_alloc_free(ptr); 570a8e1175bSopenharmony_ci (void) mbedtls_mutex_unlock(&heap.mutex); 571a8e1175bSopenharmony_ci} 572a8e1175bSopenharmony_ci#endif /* MBEDTLS_THREADING_C */ 573a8e1175bSopenharmony_ci 574a8e1175bSopenharmony_civoid mbedtls_memory_buffer_alloc_init(unsigned char *buf, size_t len) 575a8e1175bSopenharmony_ci{ 576a8e1175bSopenharmony_ci memset(&heap, 0, sizeof(buffer_alloc_ctx)); 577a8e1175bSopenharmony_ci 578a8e1175bSopenharmony_ci#if defined(MBEDTLS_THREADING_C) 579a8e1175bSopenharmony_ci mbedtls_mutex_init(&heap.mutex); 580a8e1175bSopenharmony_ci mbedtls_platform_set_calloc_free(buffer_alloc_calloc_mutexed, 581a8e1175bSopenharmony_ci buffer_alloc_free_mutexed); 582a8e1175bSopenharmony_ci#else 583a8e1175bSopenharmony_ci mbedtls_platform_set_calloc_free(buffer_alloc_calloc, buffer_alloc_free); 584a8e1175bSopenharmony_ci#endif 585a8e1175bSopenharmony_ci 586a8e1175bSopenharmony_ci if (len < sizeof(memory_header) + MBEDTLS_MEMORY_ALIGN_MULTIPLE) { 587a8e1175bSopenharmony_ci return; 588a8e1175bSopenharmony_ci } else if ((size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE) { 589a8e1175bSopenharmony_ci /* Adjust len first since buf is used in the computation */ 590a8e1175bSopenharmony_ci len -= MBEDTLS_MEMORY_ALIGN_MULTIPLE 591a8e1175bSopenharmony_ci - (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE; 592a8e1175bSopenharmony_ci buf += MBEDTLS_MEMORY_ALIGN_MULTIPLE 593a8e1175bSopenharmony_ci - (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE; 594a8e1175bSopenharmony_ci } 595a8e1175bSopenharmony_ci 596a8e1175bSopenharmony_ci memset(buf, 0, len); 597a8e1175bSopenharmony_ci 598a8e1175bSopenharmony_ci heap.buf = buf; 599a8e1175bSopenharmony_ci heap.len = len; 600a8e1175bSopenharmony_ci 601a8e1175bSopenharmony_ci heap.first = (memory_header *) buf; 602a8e1175bSopenharmony_ci heap.first->size = len - sizeof(memory_header); 603a8e1175bSopenharmony_ci heap.first->magic1 = MAGIC1; 604a8e1175bSopenharmony_ci heap.first->magic2 = MAGIC2; 605a8e1175bSopenharmony_ci heap.first_free = heap.first; 606a8e1175bSopenharmony_ci} 607a8e1175bSopenharmony_ci 608a8e1175bSopenharmony_civoid mbedtls_memory_buffer_alloc_free(void) 609a8e1175bSopenharmony_ci{ 610a8e1175bSopenharmony_ci#if defined(MBEDTLS_THREADING_C) 611a8e1175bSopenharmony_ci mbedtls_mutex_free(&heap.mutex); 612a8e1175bSopenharmony_ci#endif 613a8e1175bSopenharmony_ci mbedtls_platform_zeroize(&heap, sizeof(buffer_alloc_ctx)); 614a8e1175bSopenharmony_ci} 615a8e1175bSopenharmony_ci 616a8e1175bSopenharmony_ci#if defined(MBEDTLS_SELF_TEST) 617a8e1175bSopenharmony_cistatic int check_pointer(void *p) 618a8e1175bSopenharmony_ci{ 619a8e1175bSopenharmony_ci if (p == NULL) { 620a8e1175bSopenharmony_ci return -1; 621a8e1175bSopenharmony_ci } 622a8e1175bSopenharmony_ci 623a8e1175bSopenharmony_ci if ((size_t) p % MBEDTLS_MEMORY_ALIGN_MULTIPLE != 0) { 624a8e1175bSopenharmony_ci return -1; 625a8e1175bSopenharmony_ci } 626a8e1175bSopenharmony_ci 627a8e1175bSopenharmony_ci return 0; 628a8e1175bSopenharmony_ci} 629a8e1175bSopenharmony_ci 630a8e1175bSopenharmony_cistatic int check_all_free(void) 631a8e1175bSopenharmony_ci{ 632a8e1175bSopenharmony_ci if ( 633a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG) 634a8e1175bSopenharmony_ci heap.total_used != 0 || 635a8e1175bSopenharmony_ci#endif 636a8e1175bSopenharmony_ci heap.first != heap.first_free || 637a8e1175bSopenharmony_ci (void *) heap.first != (void *) heap.buf) { 638a8e1175bSopenharmony_ci return -1; 639a8e1175bSopenharmony_ci } 640a8e1175bSopenharmony_ci 641a8e1175bSopenharmony_ci return 0; 642a8e1175bSopenharmony_ci} 643a8e1175bSopenharmony_ci 644a8e1175bSopenharmony_ci#define TEST_ASSERT(condition) \ 645a8e1175bSopenharmony_ci if (!(condition)) \ 646a8e1175bSopenharmony_ci { \ 647a8e1175bSopenharmony_ci if (verbose != 0) \ 648a8e1175bSopenharmony_ci mbedtls_printf("failed\n"); \ 649a8e1175bSopenharmony_ci \ 650a8e1175bSopenharmony_ci ret = 1; \ 651a8e1175bSopenharmony_ci goto cleanup; \ 652a8e1175bSopenharmony_ci } 653a8e1175bSopenharmony_ci 654a8e1175bSopenharmony_ciint mbedtls_memory_buffer_alloc_self_test(int verbose) 655a8e1175bSopenharmony_ci{ 656a8e1175bSopenharmony_ci unsigned char buf[1024]; 657a8e1175bSopenharmony_ci unsigned char *p, *q, *r, *end; 658a8e1175bSopenharmony_ci int ret = 0; 659a8e1175bSopenharmony_ci 660a8e1175bSopenharmony_ci if (verbose != 0) { 661a8e1175bSopenharmony_ci mbedtls_printf(" MBA test #1 (basic alloc-free cycle): "); 662a8e1175bSopenharmony_ci } 663a8e1175bSopenharmony_ci 664a8e1175bSopenharmony_ci mbedtls_memory_buffer_alloc_init(buf, sizeof(buf)); 665a8e1175bSopenharmony_ci 666a8e1175bSopenharmony_ci p = mbedtls_calloc(1, 1); 667a8e1175bSopenharmony_ci q = mbedtls_calloc(1, 128); 668a8e1175bSopenharmony_ci r = mbedtls_calloc(1, 16); 669a8e1175bSopenharmony_ci 670a8e1175bSopenharmony_ci TEST_ASSERT(check_pointer(p) == 0 && 671a8e1175bSopenharmony_ci check_pointer(q) == 0 && 672a8e1175bSopenharmony_ci check_pointer(r) == 0); 673a8e1175bSopenharmony_ci 674a8e1175bSopenharmony_ci mbedtls_free(r); 675a8e1175bSopenharmony_ci mbedtls_free(q); 676a8e1175bSopenharmony_ci mbedtls_free(p); 677a8e1175bSopenharmony_ci 678a8e1175bSopenharmony_ci TEST_ASSERT(check_all_free() == 0); 679a8e1175bSopenharmony_ci 680a8e1175bSopenharmony_ci /* Memorize end to compare with the next test */ 681a8e1175bSopenharmony_ci end = heap.buf + heap.len; 682a8e1175bSopenharmony_ci 683a8e1175bSopenharmony_ci mbedtls_memory_buffer_alloc_free(); 684a8e1175bSopenharmony_ci 685a8e1175bSopenharmony_ci if (verbose != 0) { 686a8e1175bSopenharmony_ci mbedtls_printf("passed\n"); 687a8e1175bSopenharmony_ci } 688a8e1175bSopenharmony_ci 689a8e1175bSopenharmony_ci if (verbose != 0) { 690a8e1175bSopenharmony_ci mbedtls_printf(" MBA test #2 (buf not aligned): "); 691a8e1175bSopenharmony_ci } 692a8e1175bSopenharmony_ci 693a8e1175bSopenharmony_ci mbedtls_memory_buffer_alloc_init(buf + 1, sizeof(buf) - 1); 694a8e1175bSopenharmony_ci 695a8e1175bSopenharmony_ci TEST_ASSERT(heap.buf + heap.len == end); 696a8e1175bSopenharmony_ci 697a8e1175bSopenharmony_ci p = mbedtls_calloc(1, 1); 698a8e1175bSopenharmony_ci q = mbedtls_calloc(1, 128); 699a8e1175bSopenharmony_ci r = mbedtls_calloc(1, 16); 700a8e1175bSopenharmony_ci 701a8e1175bSopenharmony_ci TEST_ASSERT(check_pointer(p) == 0 && 702a8e1175bSopenharmony_ci check_pointer(q) == 0 && 703a8e1175bSopenharmony_ci check_pointer(r) == 0); 704a8e1175bSopenharmony_ci 705a8e1175bSopenharmony_ci mbedtls_free(r); 706a8e1175bSopenharmony_ci mbedtls_free(q); 707a8e1175bSopenharmony_ci mbedtls_free(p); 708a8e1175bSopenharmony_ci 709a8e1175bSopenharmony_ci TEST_ASSERT(check_all_free() == 0); 710a8e1175bSopenharmony_ci 711a8e1175bSopenharmony_ci mbedtls_memory_buffer_alloc_free(); 712a8e1175bSopenharmony_ci 713a8e1175bSopenharmony_ci if (verbose != 0) { 714a8e1175bSopenharmony_ci mbedtls_printf("passed\n"); 715a8e1175bSopenharmony_ci } 716a8e1175bSopenharmony_ci 717a8e1175bSopenharmony_ci if (verbose != 0) { 718a8e1175bSopenharmony_ci mbedtls_printf(" MBA test #3 (full): "); 719a8e1175bSopenharmony_ci } 720a8e1175bSopenharmony_ci 721a8e1175bSopenharmony_ci mbedtls_memory_buffer_alloc_init(buf, sizeof(buf)); 722a8e1175bSopenharmony_ci 723a8e1175bSopenharmony_ci p = mbedtls_calloc(1, sizeof(buf) - sizeof(memory_header)); 724a8e1175bSopenharmony_ci 725a8e1175bSopenharmony_ci TEST_ASSERT(check_pointer(p) == 0); 726a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_calloc(1, 1) == NULL); 727a8e1175bSopenharmony_ci 728a8e1175bSopenharmony_ci mbedtls_free(p); 729a8e1175bSopenharmony_ci 730a8e1175bSopenharmony_ci p = mbedtls_calloc(1, sizeof(buf) - 2 * sizeof(memory_header) - 16); 731a8e1175bSopenharmony_ci q = mbedtls_calloc(1, 16); 732a8e1175bSopenharmony_ci 733a8e1175bSopenharmony_ci TEST_ASSERT(check_pointer(p) == 0 && check_pointer(q) == 0); 734a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_calloc(1, 1) == NULL); 735a8e1175bSopenharmony_ci 736a8e1175bSopenharmony_ci mbedtls_free(q); 737a8e1175bSopenharmony_ci 738a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_calloc(1, 17) == NULL); 739a8e1175bSopenharmony_ci 740a8e1175bSopenharmony_ci mbedtls_free(p); 741a8e1175bSopenharmony_ci 742a8e1175bSopenharmony_ci TEST_ASSERT(check_all_free() == 0); 743a8e1175bSopenharmony_ci 744a8e1175bSopenharmony_ci mbedtls_memory_buffer_alloc_free(); 745a8e1175bSopenharmony_ci 746a8e1175bSopenharmony_ci if (verbose != 0) { 747a8e1175bSopenharmony_ci mbedtls_printf("passed\n"); 748a8e1175bSopenharmony_ci } 749a8e1175bSopenharmony_ci 750a8e1175bSopenharmony_cicleanup: 751a8e1175bSopenharmony_ci mbedtls_memory_buffer_alloc_free(); 752a8e1175bSopenharmony_ci 753a8e1175bSopenharmony_ci return ret; 754a8e1175bSopenharmony_ci} 755a8e1175bSopenharmony_ci#endif /* MBEDTLS_SELF_TEST */ 756a8e1175bSopenharmony_ci 757a8e1175bSopenharmony_ci#endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */ 758