mem.c revision 296465
1/* crypto/mem.c */ 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * 9 * This library is free for commercial and non-commercial use as long as 10 * the following conditions are aheared to. The following conditions 11 * apply to all code found in this distribution, be it the RC4, RSA, 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13 * included with this distribution is covered by the same copyright terms 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15 * 16 * Copyright remains Eric Young's, and as such any Copyright notices in 17 * the code are not to be removed. 18 * If this package is used in a product, Eric Young should be given attribution 19 * as the author of the parts of the library used. 20 * This can be in the form of a textual message at program startup or 21 * in documentation (online or textual) provided with the package. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * "This product includes cryptographic software written by 34 * Eric Young (eay@cryptsoft.com)" 35 * The word 'cryptographic' can be left out if the rouines from the library 36 * being used are not cryptographic related :-). 37 * 4. If you include any Windows specific code (or a derivative thereof) from 38 * the apps directory (application code) you must include an acknowledgement: 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * The licence and distribution terms for any publically available version or 54 * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] 57 */ 58 59#include <stdio.h> 60#include <stdlib.h> 61#include <openssl/crypto.h> 62#include "cryptlib.h" 63 64static int allow_customize = 1; /* we provide flexible functions for */ 65static int allow_customize_debug = 1; /* exchanging memory-related functions 66 * at run-time, but this must be done 67 * before any blocks are actually 68 * allocated; or we'll run into huge 69 * problems when malloc/free pairs 70 * don't match etc. */ 71 72/* 73 * the following pointers may be changed as long as 'allow_customize' is set 74 */ 75 76static void *(*malloc_func) (size_t) = malloc; 77static void *default_malloc_ex(size_t num, const char *file, int line) 78{ 79 return malloc_func(num); 80} 81 82static void *(*malloc_ex_func) (size_t, const char *file, int line) 83 = default_malloc_ex; 84 85static void *(*realloc_func) (void *, size_t) = realloc; 86static void *default_realloc_ex(void *str, size_t num, 87 const char *file, int line) 88{ 89 return realloc_func(str, num); 90} 91 92static void *(*realloc_ex_func) (void *, size_t, const char *file, int line) 93 = default_realloc_ex; 94 95static void (*free_func) (void *) = free; 96 97static void *(*malloc_locked_func) (size_t) = malloc; 98static void *default_malloc_locked_ex(size_t num, const char *file, int line) 99{ 100 return malloc_locked_func(num); 101} 102 103static void *(*malloc_locked_ex_func) (size_t, const char *file, int line) 104 = default_malloc_locked_ex; 105 106static void (*free_locked_func) (void *) = free; 107 108/* may be changed as long as 'allow_customize_debug' is set */ 109/* XXX use correct function pointer types */ 110#if defined(CRYPTO_MDEBUG) && !defined(OPENSSL_FIPS) 111/* use default functions from mem_dbg.c */ 112static void (*malloc_debug_func) (void *, int, const char *, int, int) 113 = CRYPTO_dbg_malloc; 114static void (*realloc_debug_func) (void *, void *, int, const char *, int, 115 int) 116 = CRYPTO_dbg_realloc; 117static void (*free_debug_func) (void *, int) = CRYPTO_dbg_free; 118static void (*set_debug_options_func) (long) = CRYPTO_dbg_set_options; 119static long (*get_debug_options_func) (void) = CRYPTO_dbg_get_options; 120 121static int (*push_info_func) (const char *info, const char *file, int line) 122 = CRYPTO_dbg_push_info; 123static int (*pop_info_func) (void) 124 = CRYPTO_dbg_pop_info; 125static int (*remove_all_info_func) (void) 126 = CRYPTO_dbg_remove_all_info; 127 128#else 129/* 130 * applications can use CRYPTO_malloc_debug_init() to select above case at 131 * run-time 132 */ 133static void (*malloc_debug_func) (void *, int, const char *, int, int) = NULL; 134static void (*realloc_debug_func) (void *, void *, int, const char *, int, 135 int) 136 = NULL; 137static void (*free_debug_func) (void *, int) = NULL; 138static void (*set_debug_options_func) (long) = NULL; 139static long (*get_debug_options_func) (void) = NULL; 140 141static int (*push_info_func) (const char *info, const char *file, int line) 142 = NULL; 143static int (*pop_info_func) (void) = NULL; 144static int (*remove_all_info_func) (void) = NULL; 145 146#endif 147 148int CRYPTO_set_mem_functions(void *(*m) (size_t), void *(*r) (void *, size_t), 149 void (*f) (void *)) 150{ 151 if (!allow_customize) 152 return 0; 153 if ((m == 0) || (r == 0) || (f == 0)) 154 return 0; 155 malloc_func = m; 156 malloc_ex_func = default_malloc_ex; 157 realloc_func = r; 158 realloc_ex_func = default_realloc_ex; 159 free_func = f; 160 malloc_locked_func = m; 161 malloc_locked_ex_func = default_malloc_locked_ex; 162 free_locked_func = f; 163 return 1; 164} 165 166int CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int), 167 void *(*r) (void *, size_t, const char *, 168 int), void (*f) (void *)) 169{ 170 if (!allow_customize) 171 return 0; 172 if ((m == 0) || (r == 0) || (f == 0)) 173 return 0; 174 malloc_func = 0; 175 malloc_ex_func = m; 176 realloc_func = 0; 177 realloc_ex_func = r; 178 free_func = f; 179 malloc_locked_func = 0; 180 malloc_locked_ex_func = m; 181 free_locked_func = f; 182 return 1; 183} 184 185int CRYPTO_set_locked_mem_functions(void *(*m) (size_t), void (*f) (void *)) 186{ 187 if (!allow_customize) 188 return 0; 189 if ((m == NULL) || (f == NULL)) 190 return 0; 191 malloc_locked_func = m; 192 malloc_locked_ex_func = default_malloc_locked_ex; 193 free_locked_func = f; 194 return 1; 195} 196 197int CRYPTO_set_locked_mem_ex_functions(void *(*m) (size_t, const char *, int), 198 void (*f) (void *)) 199{ 200 if (!allow_customize) 201 return 0; 202 if ((m == NULL) || (f == NULL)) 203 return 0; 204 malloc_locked_func = 0; 205 malloc_locked_ex_func = m; 206 free_func = f; 207 return 1; 208} 209 210int CRYPTO_set_mem_debug_functions(void (*m) 211 (void *, int, const char *, int, int), 212 void (*r) (void *, void *, int, 213 const char *, int, int), 214 void (*f) (void *, int), void (*so) (long), 215 long (*go) (void)) 216{ 217 if (!allow_customize_debug) 218 return 0; 219 malloc_debug_func = m; 220 realloc_debug_func = r; 221 free_debug_func = f; 222 set_debug_options_func = so; 223 get_debug_options_func = go; 224 return 1; 225} 226 227void CRYPTO_set_mem_info_functions(int (*push_info_fn) 228 (const char *info, const char *file, 229 int line), int (*pop_info_fn) (void), 230 int (*remove_all_info_fn) (void)) 231{ 232 push_info_func = push_info_fn; 233 pop_info_func = pop_info_fn; 234 remove_all_info_func = remove_all_info_fn; 235} 236 237void CRYPTO_get_mem_functions(void *(**m) (size_t), 238 void *(**r) (void *, size_t), 239 void (**f) (void *)) 240{ 241 if (m != NULL) 242 *m = (malloc_ex_func == default_malloc_ex) ? malloc_func : 0; 243 if (r != NULL) 244 *r = (realloc_ex_func == default_realloc_ex) ? realloc_func : 0; 245 if (f != NULL) 246 *f = free_func; 247} 248 249void CRYPTO_get_mem_ex_functions(void *(**m) (size_t, const char *, int), 250 void *(**r) (void *, size_t, const char *, 251 int), void (**f) (void *)) 252{ 253 if (m != NULL) 254 *m = (malloc_ex_func != default_malloc_ex) ? malloc_ex_func : 0; 255 if (r != NULL) 256 *r = (realloc_ex_func != default_realloc_ex) ? realloc_ex_func : 0; 257 if (f != NULL) 258 *f = free_func; 259} 260 261void CRYPTO_get_locked_mem_functions(void *(**m) (size_t), 262 void (**f) (void *)) 263{ 264 if (m != NULL) 265 *m = (malloc_locked_ex_func == default_malloc_locked_ex) ? 266 malloc_locked_func : 0; 267 if (f != NULL) 268 *f = free_locked_func; 269} 270 271void CRYPTO_get_locked_mem_ex_functions(void 272 *(**m) (size_t, const char *, int), 273 void (**f) (void *)) 274{ 275 if (m != NULL) 276 *m = (malloc_locked_ex_func != default_malloc_locked_ex) ? 277 malloc_locked_ex_func : 0; 278 if (f != NULL) 279 *f = free_locked_func; 280} 281 282void CRYPTO_get_mem_debug_functions(void (**m) 283 (void *, int, const char *, int, int), 284 void (**r) (void *, void *, int, 285 const char *, int, int), 286 void (**f) (void *, int), 287 void (**so) (long), long (**go) (void)) 288{ 289 if (m != NULL) 290 *m = malloc_debug_func; 291 if (r != NULL) 292 *r = realloc_debug_func; 293 if (f != NULL) 294 *f = free_debug_func; 295 if (so != NULL) 296 *so = set_debug_options_func; 297 if (go != NULL) 298 *go = get_debug_options_func; 299} 300 301void *CRYPTO_malloc_locked(int num, const char *file, int line) 302{ 303 void *ret = NULL; 304 extern unsigned char cleanse_ctr; 305 306 if (num <= 0) 307 return NULL; 308 309 allow_customize = 0; 310 if (malloc_debug_func != NULL) { 311 allow_customize_debug = 0; 312 malloc_debug_func(NULL, num, file, line, 0); 313 } 314 ret = malloc_locked_ex_func(num, file, line); 315#ifdef LEVITTE_DEBUG_MEM 316 fprintf(stderr, "LEVITTE_DEBUG_MEM: > 0x%p (%d)\n", ret, num); 317#endif 318 if (malloc_debug_func != NULL) 319 malloc_debug_func(ret, num, file, line, 1); 320 321 /* 322 * Create a dependency on the value of 'cleanse_ctr' so our memory 323 * sanitisation function can't be optimised out. NB: We only do this for 324 * >2Kb so the overhead doesn't bother us. 325 */ 326 if (ret && (num > 2048)) 327 ((unsigned char *)ret)[0] = cleanse_ctr; 328 329 return ret; 330} 331 332void CRYPTO_free_locked(void *str) 333{ 334 if (free_debug_func != NULL) 335 free_debug_func(str, 0); 336#ifdef LEVITTE_DEBUG_MEM 337 fprintf(stderr, "LEVITTE_DEBUG_MEM: < 0x%p\n", str); 338#endif 339 free_locked_func(str); 340 if (free_debug_func != NULL) 341 free_debug_func(NULL, 1); 342} 343 344void *CRYPTO_malloc(int num, const char *file, int line) 345{ 346 void *ret = NULL; 347 extern unsigned char cleanse_ctr; 348 349 if (num <= 0) 350 return NULL; 351 352 allow_customize = 0; 353 if (malloc_debug_func != NULL) { 354 allow_customize_debug = 0; 355 malloc_debug_func(NULL, num, file, line, 0); 356 } 357 ret = malloc_ex_func(num, file, line); 358#ifdef LEVITTE_DEBUG_MEM 359 fprintf(stderr, "LEVITTE_DEBUG_MEM: > 0x%p (%d)\n", ret, num); 360#endif 361 if (malloc_debug_func != NULL) 362 malloc_debug_func(ret, num, file, line, 1); 363 364 /* 365 * Create a dependency on the value of 'cleanse_ctr' so our memory 366 * sanitisation function can't be optimised out. NB: We only do this for 367 * >2Kb so the overhead doesn't bother us. 368 */ 369 if (ret && (num > 2048)) 370 ((unsigned char *)ret)[0] = cleanse_ctr; 371 372 return ret; 373} 374 375void *CRYPTO_realloc(void *str, int num, const char *file, int line) 376{ 377 void *ret = NULL; 378 379 if (str == NULL) 380 return CRYPTO_malloc(num, file, line); 381 382 if (num <= 0) 383 return NULL; 384 385 if (realloc_debug_func != NULL) 386 realloc_debug_func(str, NULL, num, file, line, 0); 387 ret = realloc_ex_func(str, num, file, line); 388#ifdef LEVITTE_DEBUG_MEM 389 fprintf(stderr, "LEVITTE_DEBUG_MEM: | 0x%p -> 0x%p (%d)\n", str, 390 ret, num); 391#endif 392 if (realloc_debug_func != NULL) 393 realloc_debug_func(str, ret, num, file, line, 1); 394 395 return ret; 396} 397 398void *CRYPTO_realloc_clean(void *str, int old_len, int num, const char *file, 399 int line) 400{ 401 void *ret = NULL; 402 403 if (str == NULL) 404 return CRYPTO_malloc(num, file, line); 405 406 if (num <= 0) 407 return NULL; 408 409 /* 410 * We don't support shrinking the buffer. Note the memcpy that copies 411 * |old_len| bytes to the new buffer, below. 412 */ 413 if (num < old_len) 414 return NULL; 415 416 if (realloc_debug_func != NULL) 417 realloc_debug_func(str, NULL, num, file, line, 0); 418 ret = malloc_ex_func(num, file, line); 419 if (ret) { 420 memcpy(ret, str, old_len); 421 OPENSSL_cleanse(str, old_len); 422 free_func(str); 423 } 424#ifdef LEVITTE_DEBUG_MEM 425 fprintf(stderr, 426 "LEVITTE_DEBUG_MEM: | 0x%p -> 0x%p (%d)\n", 427 str, ret, num); 428#endif 429 if (realloc_debug_func != NULL) 430 realloc_debug_func(str, ret, num, file, line, 1); 431 432 return ret; 433} 434 435void CRYPTO_free(void *str) 436{ 437 if (free_debug_func != NULL) 438 free_debug_func(str, 0); 439#ifdef LEVITTE_DEBUG_MEM 440 fprintf(stderr, "LEVITTE_DEBUG_MEM: < 0x%p\n", str); 441#endif 442 free_func(str); 443 if (free_debug_func != NULL) 444 free_debug_func(NULL, 1); 445} 446 447void *CRYPTO_remalloc(void *a, int num, const char *file, int line) 448{ 449 if (a != NULL) 450 OPENSSL_free(a); 451 a = (char *)OPENSSL_malloc(num); 452 return (a); 453} 454 455void CRYPTO_set_mem_debug_options(long bits) 456{ 457 if (set_debug_options_func != NULL) 458 set_debug_options_func(bits); 459} 460 461long CRYPTO_get_mem_debug_options(void) 462{ 463 if (get_debug_options_func != NULL) 464 return get_debug_options_func(); 465 return 0; 466} 467 468int CRYPTO_push_info_(const char *info, const char *file, int line) 469{ 470 if (push_info_func) 471 return push_info_func(info, file, line); 472 return 1; 473} 474 475int CRYPTO_pop_info(void) 476{ 477 if (pop_info_func) 478 return pop_info_func(); 479 return 1; 480} 481 482int CRYPTO_remove_all_info(void) 483{ 484 if (remove_all_info_func) 485 return remove_all_info_func(); 486 return 1; 487} 488