mem.c revision 280304
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#ifdef CRYPTO_MDEBUG 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#else 121/* 122 * applications can use CRYPTO_malloc_debug_init() to select above case at 123 * run-time 124 */ 125static void (*malloc_debug_func) (void *, int, const char *, int, int) = NULL; 126static void (*realloc_debug_func) (void *, void *, int, const char *, int, 127 int) 128 = NULL; 129static void (*free_debug_func) (void *, int) = NULL; 130static void (*set_debug_options_func) (long) = NULL; 131static long (*get_debug_options_func) (void) = NULL; 132#endif 133 134int CRYPTO_set_mem_functions(void *(*m) (size_t), void *(*r) (void *, size_t), 135 void (*f) (void *)) 136{ 137 /* Dummy call just to ensure OPENSSL_init() gets linked in */ 138 OPENSSL_init(); 139 if (!allow_customize) 140 return 0; 141 if ((m == 0) || (r == 0) || (f == 0)) 142 return 0; 143 malloc_func = m; 144 malloc_ex_func = default_malloc_ex; 145 realloc_func = r; 146 realloc_ex_func = default_realloc_ex; 147 free_func = f; 148 malloc_locked_func = m; 149 malloc_locked_ex_func = default_malloc_locked_ex; 150 free_locked_func = f; 151 return 1; 152} 153 154int CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int), 155 void *(*r) (void *, size_t, const char *, 156 int), void (*f) (void *)) 157{ 158 if (!allow_customize) 159 return 0; 160 if ((m == 0) || (r == 0) || (f == 0)) 161 return 0; 162 malloc_func = 0; 163 malloc_ex_func = m; 164 realloc_func = 0; 165 realloc_ex_func = r; 166 free_func = f; 167 malloc_locked_func = 0; 168 malloc_locked_ex_func = m; 169 free_locked_func = f; 170 return 1; 171} 172 173int CRYPTO_set_locked_mem_functions(void *(*m) (size_t), void (*f) (void *)) 174{ 175 if (!allow_customize) 176 return 0; 177 if ((m == NULL) || (f == NULL)) 178 return 0; 179 malloc_locked_func = m; 180 malloc_locked_ex_func = default_malloc_locked_ex; 181 free_locked_func = f; 182 return 1; 183} 184 185int CRYPTO_set_locked_mem_ex_functions(void *(*m) (size_t, const char *, int), 186 void (*f) (void *)) 187{ 188 if (!allow_customize) 189 return 0; 190 if ((m == NULL) || (f == NULL)) 191 return 0; 192 malloc_locked_func = 0; 193 malloc_locked_ex_func = m; 194 free_func = f; 195 return 1; 196} 197 198int CRYPTO_set_mem_debug_functions(void (*m) 199 (void *, int, const char *, int, int), 200 void (*r) (void *, void *, int, 201 const char *, int, int), 202 void (*f) (void *, int), void (*so) (long), 203 long (*go) (void)) 204{ 205 if (!allow_customize_debug) 206 return 0; 207 OPENSSL_init(); 208 malloc_debug_func = m; 209 realloc_debug_func = r; 210 free_debug_func = f; 211 set_debug_options_func = so; 212 get_debug_options_func = go; 213 return 1; 214} 215 216void CRYPTO_get_mem_functions(void *(**m) (size_t), 217 void *(**r) (void *, size_t), 218 void (**f) (void *)) 219{ 220 if (m != NULL) 221 *m = (malloc_ex_func == default_malloc_ex) ? malloc_func : 0; 222 if (r != NULL) 223 *r = (realloc_ex_func == default_realloc_ex) ? realloc_func : 0; 224 if (f != NULL) 225 *f = free_func; 226} 227 228void CRYPTO_get_mem_ex_functions(void *(**m) (size_t, const char *, int), 229 void *(**r) (void *, size_t, const char *, 230 int), void (**f) (void *)) 231{ 232 if (m != NULL) 233 *m = (malloc_ex_func != default_malloc_ex) ? malloc_ex_func : 0; 234 if (r != NULL) 235 *r = (realloc_ex_func != default_realloc_ex) ? realloc_ex_func : 0; 236 if (f != NULL) 237 *f = free_func; 238} 239 240void CRYPTO_get_locked_mem_functions(void *(**m) (size_t), 241 void (**f) (void *)) 242{ 243 if (m != NULL) 244 *m = (malloc_locked_ex_func == default_malloc_locked_ex) ? 245 malloc_locked_func : 0; 246 if (f != NULL) 247 *f = free_locked_func; 248} 249 250void CRYPTO_get_locked_mem_ex_functions(void 251 *(**m) (size_t, const char *, int), 252 void (**f) (void *)) 253{ 254 if (m != NULL) 255 *m = (malloc_locked_ex_func != default_malloc_locked_ex) ? 256 malloc_locked_ex_func : 0; 257 if (f != NULL) 258 *f = free_locked_func; 259} 260 261void CRYPTO_get_mem_debug_functions(void (**m) 262 (void *, int, const char *, int, int), 263 void (**r) (void *, void *, int, 264 const char *, int, int), 265 void (**f) (void *, int), 266 void (**so) (long), long (**go) (void)) 267{ 268 if (m != NULL) 269 *m = malloc_debug_func; 270 if (r != NULL) 271 *r = realloc_debug_func; 272 if (f != NULL) 273 *f = free_debug_func; 274 if (so != NULL) 275 *so = set_debug_options_func; 276 if (go != NULL) 277 *go = get_debug_options_func; 278} 279 280void *CRYPTO_malloc_locked(int num, const char *file, int line) 281{ 282 void *ret = NULL; 283 284 if (num <= 0) 285 return NULL; 286 287 if (allow_customize) 288 allow_customize = 0; 289 if (malloc_debug_func != NULL) { 290 if (allow_customize_debug) 291 allow_customize_debug = 0; 292 malloc_debug_func(NULL, num, file, line, 0); 293 } 294 ret = malloc_locked_ex_func(num, file, line); 295#ifdef LEVITTE_DEBUG_MEM 296 fprintf(stderr, "LEVITTE_DEBUG_MEM: > 0x%p (%d)\n", ret, num); 297#endif 298 if (malloc_debug_func != NULL) 299 malloc_debug_func(ret, num, file, line, 1); 300 301#ifndef OPENSSL_CPUID_OBJ 302 /* 303 * Create a dependency on the value of 'cleanse_ctr' so our memory 304 * sanitisation function can't be optimised out. NB: We only do this for 305 * >2Kb so the overhead doesn't bother us. 306 */ 307 if (ret && (num > 2048)) { 308 extern unsigned char cleanse_ctr; 309 ((unsigned char *)ret)[0] = cleanse_ctr; 310 } 311#endif 312 313 return ret; 314} 315 316void CRYPTO_free_locked(void *str) 317{ 318 if (free_debug_func != NULL) 319 free_debug_func(str, 0); 320#ifdef LEVITTE_DEBUG_MEM 321 fprintf(stderr, "LEVITTE_DEBUG_MEM: < 0x%p\n", str); 322#endif 323 free_locked_func(str); 324 if (free_debug_func != NULL) 325 free_debug_func(NULL, 1); 326} 327 328void *CRYPTO_malloc(int num, const char *file, int line) 329{ 330 void *ret = NULL; 331 332 if (num <= 0) 333 return NULL; 334 335 if (allow_customize) 336 allow_customize = 0; 337 if (malloc_debug_func != NULL) { 338 if (allow_customize_debug) 339 allow_customize_debug = 0; 340 malloc_debug_func(NULL, num, file, line, 0); 341 } 342 ret = malloc_ex_func(num, file, line); 343#ifdef LEVITTE_DEBUG_MEM 344 fprintf(stderr, "LEVITTE_DEBUG_MEM: > 0x%p (%d)\n", ret, num); 345#endif 346 if (malloc_debug_func != NULL) 347 malloc_debug_func(ret, num, file, line, 1); 348 349#ifndef OPENSSL_CPUID_OBJ 350 /* 351 * Create a dependency on the value of 'cleanse_ctr' so our memory 352 * sanitisation function can't be optimised out. NB: We only do this for 353 * >2Kb so the overhead doesn't bother us. 354 */ 355 if (ret && (num > 2048)) { 356 extern unsigned char cleanse_ctr; 357 ((unsigned char *)ret)[0] = cleanse_ctr; 358 } 359#endif 360 361 return ret; 362} 363 364char *CRYPTO_strdup(const char *str, const char *file, int line) 365{ 366 char *ret = CRYPTO_malloc(strlen(str) + 1, file, line); 367 368 strcpy(ret, str); 369 return ret; 370} 371 372void *CRYPTO_realloc(void *str, int num, const char *file, int line) 373{ 374 void *ret = NULL; 375 376 if (str == NULL) 377 return CRYPTO_malloc(num, file, line); 378 379 if (num <= 0) 380 return NULL; 381 382 if (realloc_debug_func != NULL) 383 realloc_debug_func(str, NULL, num, file, line, 0); 384 ret = realloc_ex_func(str, num, file, line); 385#ifdef LEVITTE_DEBUG_MEM 386 fprintf(stderr, "LEVITTE_DEBUG_MEM: | 0x%p -> 0x%p (%d)\n", str, 387 ret, num); 388#endif 389 if (realloc_debug_func != NULL) 390 realloc_debug_func(str, ret, num, file, line, 1); 391 392 return ret; 393} 394 395void *CRYPTO_realloc_clean(void *str, int old_len, int num, const char *file, 396 int line) 397{ 398 void *ret = NULL; 399 400 if (str == NULL) 401 return CRYPTO_malloc(num, file, line); 402 403 if (num <= 0) 404 return NULL; 405 406 /* 407 * We don't support shrinking the buffer. Note the memcpy that copies 408 * |old_len| bytes to the new buffer, below. 409 */ 410 if (num < old_len) 411 return NULL; 412 413 if (realloc_debug_func != NULL) 414 realloc_debug_func(str, NULL, num, file, line, 0); 415 ret = malloc_ex_func(num, file, line); 416 if (ret) { 417 memcpy(ret, str, old_len); 418 OPENSSL_cleanse(str, old_len); 419 free_func(str); 420 } 421#ifdef LEVITTE_DEBUG_MEM 422 fprintf(stderr, 423 "LEVITTE_DEBUG_MEM: | 0x%p -> 0x%p (%d)\n", 424 str, ret, num); 425#endif 426 if (realloc_debug_func != NULL) 427 realloc_debug_func(str, ret, num, file, line, 1); 428 429 return ret; 430} 431 432void CRYPTO_free(void *str) 433{ 434 if (free_debug_func != NULL) 435 free_debug_func(str, 0); 436#ifdef LEVITTE_DEBUG_MEM 437 fprintf(stderr, "LEVITTE_DEBUG_MEM: < 0x%p\n", str); 438#endif 439 free_func(str); 440 if (free_debug_func != NULL) 441 free_debug_func(NULL, 1); 442} 443 444void *CRYPTO_remalloc(void *a, int num, const char *file, int line) 445{ 446 if (a != NULL) 447 OPENSSL_free(a); 448 a = (char *)OPENSSL_malloc(num); 449 return (a); 450} 451 452void CRYPTO_set_mem_debug_options(long bits) 453{ 454 if (set_debug_options_func != NULL) 455 set_debug_options_func(bits); 456} 457 458long CRYPTO_get_mem_debug_options(void) 459{ 460 if (get_debug_options_func != NULL) 461 return get_debug_options_func(); 462 return 0; 463} 464