14ec2eca9Schristos /* 2*3afa6631Schristos * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. 3a89c9211Schristos * 44ec2eca9Schristos * Licensed under the OpenSSL license (the "License"). You may not use 54ec2eca9Schristos * this file except in compliance with the License. You can obtain a copy 64ec2eca9Schristos * in the file LICENSE in the source distribution or at 74ec2eca9Schristos * https://www.openssl.org/source/license.html 8a89c9211Schristos */ 9a89c9211Schristos 10a89c9211Schristos #include <stdio.h> 11a89c9211Schristos #include <stdlib.h> 124ec2eca9Schristos #include <limits.h> 13a89c9211Schristos #include <openssl/crypto.h> 144ec2eca9Schristos #include "internal/cryptlib.h" 15a89c9211Schristos 16d572d25fSspz /* 17d572d25fSspz * the following pointers may be changed as long as 'allow_customize' is set 18d572d25fSspz */ 194ec2eca9Schristos static int allow_customize = 1; 20a89c9211Schristos 214ec2eca9Schristos static void *(*malloc_impl)(size_t, const char *, int) 224ec2eca9Schristos = CRYPTO_malloc; 234ec2eca9Schristos static void *(*realloc_impl)(void *, size_t, const char *, int) 244ec2eca9Schristos = CRYPTO_realloc; 254ec2eca9Schristos static void (*free_impl)(void *, const char *, int) 264ec2eca9Schristos = CRYPTO_free; 274ec2eca9Schristos 284ec2eca9Schristos #ifndef OPENSSL_NO_CRYPTO_MDEBUG 294ec2eca9Schristos static int call_malloc_debug = 1; 304ec2eca9Schristos #else 314ec2eca9Schristos static int call_malloc_debug = 0; 324ec2eca9Schristos #endif 334ec2eca9Schristos 344ec2eca9Schristos int CRYPTO_set_mem_functions( 354ec2eca9Schristos void *(*m)(size_t, const char *, int), 364ec2eca9Schristos void *(*r)(void *, size_t, const char *, int), 374ec2eca9Schristos void (*f)(void *, const char *, int)) 38d572d25fSspz { 394ec2eca9Schristos if (!allow_customize) 404ec2eca9Schristos return 0; 414ec2eca9Schristos if (m) 424ec2eca9Schristos malloc_impl = m; 434ec2eca9Schristos if (r) 444ec2eca9Schristos realloc_impl = r; 454ec2eca9Schristos if (f) 464ec2eca9Schristos free_impl = f; 474ec2eca9Schristos return 1; 48d572d25fSspz } 49d572d25fSspz 504ec2eca9Schristos int CRYPTO_set_mem_debug(int flag) 514ec2eca9Schristos { 524ec2eca9Schristos if (!allow_customize) 534ec2eca9Schristos return 0; 544ec2eca9Schristos call_malloc_debug = flag; 554ec2eca9Schristos return 1; 564ec2eca9Schristos } 57a89c9211Schristos 584ec2eca9Schristos void CRYPTO_get_mem_functions( 594ec2eca9Schristos void *(**m)(size_t, const char *, int), 604ec2eca9Schristos void *(**r)(void *, size_t, const char *, int), 614ec2eca9Schristos void (**f)(void *, const char *, int)) 624ec2eca9Schristos { 634ec2eca9Schristos if (m != NULL) 644ec2eca9Schristos *m = malloc_impl; 654ec2eca9Schristos if (r != NULL) 664ec2eca9Schristos *r = realloc_impl; 674ec2eca9Schristos if (f != NULL) 684ec2eca9Schristos *f = free_impl; 694ec2eca9Schristos } 704ec2eca9Schristos 714ec2eca9Schristos void *CRYPTO_malloc(size_t num, const char *file, int line) 724ec2eca9Schristos { 734ec2eca9Schristos void *ret = NULL; 744ec2eca9Schristos 754ec2eca9Schristos if (malloc_impl != NULL && malloc_impl != CRYPTO_malloc) 764ec2eca9Schristos return malloc_impl(num, file, line); 774ec2eca9Schristos 784ec2eca9Schristos if (num == 0) 794ec2eca9Schristos return NULL; 804ec2eca9Schristos 81*3afa6631Schristos if (allow_customize) { 82*3afa6631Schristos /* 83*3afa6631Schristos * Disallow customization after the first allocation. We only set this 84*3afa6631Schristos * if necessary to avoid a store to the same cache line on every 85*3afa6631Schristos * allocation. 86*3afa6631Schristos */ 874ec2eca9Schristos allow_customize = 0; 88*3afa6631Schristos } 894ec2eca9Schristos #ifndef OPENSSL_NO_CRYPTO_MDEBUG 904ec2eca9Schristos if (call_malloc_debug) { 914ec2eca9Schristos CRYPTO_mem_debug_malloc(NULL, num, 0, file, line); 924ec2eca9Schristos ret = malloc(num); 934ec2eca9Schristos CRYPTO_mem_debug_malloc(ret, num, 1, file, line); 944ec2eca9Schristos } else { 954ec2eca9Schristos ret = malloc(num); 964ec2eca9Schristos } 974ec2eca9Schristos #else 984ec2eca9Schristos osslargused(file); osslargused(line); 994ec2eca9Schristos ret = malloc(num); 1007fa80bafSspz #endif 1017fa80bafSspz 1024ec2eca9Schristos return ret; 1034ec2eca9Schristos } 1044ec2eca9Schristos 1054ec2eca9Schristos void *CRYPTO_zalloc(size_t num, const char *file, int line) 1064ec2eca9Schristos { 1074ec2eca9Schristos void *ret = CRYPTO_malloc(num, file, line); 1084ec2eca9Schristos 1094ec2eca9Schristos if (ret != NULL) 1104ec2eca9Schristos memset(ret, 0, num); 1114ec2eca9Schristos return ret; 1124ec2eca9Schristos } 1134ec2eca9Schristos 1144ec2eca9Schristos void *CRYPTO_realloc(void *str, size_t num, const char *file, int line) 1154ec2eca9Schristos { 1164ec2eca9Schristos if (realloc_impl != NULL && realloc_impl != &CRYPTO_realloc) 1174ec2eca9Schristos return realloc_impl(str, num, file, line); 1184ec2eca9Schristos 1194ec2eca9Schristos if (str == NULL) 1204ec2eca9Schristos return CRYPTO_malloc(num, file, line); 1214ec2eca9Schristos 1224ec2eca9Schristos if (num == 0) { 1234ec2eca9Schristos CRYPTO_free(str, file, line); 1244ec2eca9Schristos return NULL; 1254ec2eca9Schristos } 1264ec2eca9Schristos 1274ec2eca9Schristos #ifndef OPENSSL_NO_CRYPTO_MDEBUG 1284ec2eca9Schristos if (call_malloc_debug) { 1294ec2eca9Schristos void *ret; 1304ec2eca9Schristos CRYPTO_mem_debug_realloc(str, NULL, num, 0, file, line); 1314ec2eca9Schristos ret = realloc(str, num); 1324ec2eca9Schristos CRYPTO_mem_debug_realloc(str, ret, num, 1, file, line); 1334ec2eca9Schristos return ret; 1344ec2eca9Schristos } 1354ec2eca9Schristos #else 1364ec2eca9Schristos osslargused(file); osslargused(line); 1374ec2eca9Schristos #endif 1384ec2eca9Schristos return realloc(str, num); 1394ec2eca9Schristos 1404ec2eca9Schristos } 1414ec2eca9Schristos 1424ec2eca9Schristos void *CRYPTO_clear_realloc(void *str, size_t old_len, size_t num, 143a89c9211Schristos const char *file, int line) 144d572d25fSspz { 145a89c9211Schristos void *ret = NULL; 146a89c9211Schristos 147a89c9211Schristos if (str == NULL) 148a89c9211Schristos return CRYPTO_malloc(num, file, line); 149a89c9211Schristos 1504ec2eca9Schristos if (num == 0) { 1514ec2eca9Schristos CRYPTO_clear_free(str, old_len, file, line); 152d572d25fSspz return NULL; 153a89c9211Schristos } 154a89c9211Schristos 1554ec2eca9Schristos /* Can't shrink the buffer since memcpy below copies |old_len| bytes. */ 1564ec2eca9Schristos if (num < old_len) { 1574ec2eca9Schristos OPENSSL_cleanse((char*)str + num, old_len - num); 1584ec2eca9Schristos return str; 1594ec2eca9Schristos } 160a89c9211Schristos 1614ec2eca9Schristos ret = CRYPTO_malloc(num, file, line); 1624ec2eca9Schristos if (ret != NULL) { 163a89c9211Schristos memcpy(ret, str, old_len); 1644ec2eca9Schristos CRYPTO_clear_free(str, old_len, file, line); 165a89c9211Schristos } 166a89c9211Schristos return ret; 167a89c9211Schristos } 168a89c9211Schristos 1694ec2eca9Schristos void CRYPTO_free(void *str, const char *file, int line) 170a89c9211Schristos { 1714ec2eca9Schristos if (free_impl != NULL && free_impl != &CRYPTO_free) { 1724ec2eca9Schristos free_impl(str, file, line); 1734ec2eca9Schristos return; 1744ec2eca9Schristos } 1754ec2eca9Schristos 1764ec2eca9Schristos #ifndef OPENSSL_NO_CRYPTO_MDEBUG 1774ec2eca9Schristos if (call_malloc_debug) { 1784ec2eca9Schristos CRYPTO_mem_debug_free(str, 0, file, line); 1794ec2eca9Schristos free(str); 1804ec2eca9Schristos CRYPTO_mem_debug_free(str, 1, file, line); 1814ec2eca9Schristos } else { 1824ec2eca9Schristos free(str); 1834ec2eca9Schristos } 1844ec2eca9Schristos #else 1854ec2eca9Schristos free(str); 186a89c9211Schristos #endif 187a89c9211Schristos } 188a89c9211Schristos 1894ec2eca9Schristos void CRYPTO_clear_free(void *str, size_t num, const char *file, int line) 190a89c9211Schristos { 1914ec2eca9Schristos if (str == NULL) 1924ec2eca9Schristos return; 1934ec2eca9Schristos if (num) 1944ec2eca9Schristos OPENSSL_cleanse(str, num); 1954ec2eca9Schristos CRYPTO_free(str, file, line); 196a89c9211Schristos } 197