malloc.cc revision d9e397b599b13d642138480a28c14db7a136bf0
1d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Copyright (c) 2014, Google Inc. 2d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 3d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Permission to use, copy, modify, and/or distribute this software for any 4d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * purpose with or without fee is hereby granted, provided that the above 5d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * copyright notice and this permission notice appear in all copies. 6d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 7d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 10d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 12d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 13d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ 14d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 15d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/base.h> 16d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 17d9e397b599b13d642138480a28c14db7a136bf0Adam Langley// This file isn't built on ARM or Aarch64 because we link statically in those 18d9e397b599b13d642138480a28c14db7a136bf0Adam Langley// builds and trying to override malloc in a static link doesn't work. 19d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#if defined(__linux__) && !defined(OPENSSL_ARM) && !defined(OPENSSL_AARCH64) 20d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 21d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <stdint.h> 22d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <stdlib.h> 23d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <unistd.h> 24d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <unistd.h> 25d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <stdio.h> 26d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 27d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <new> 28d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 29d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 30d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* This file defines overrides for the standard allocation functions that allow 31d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * a given allocation to be made to fail for testing. If the program is run 32d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * with MALLOC_NUMBER_TO_FAIL set to a base-10 number then that allocation will 33d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * return NULL. If MALLOC_ABORT_ON_FAIL is also defined then the allocation 34d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * will abort() rather than return NULL. 35d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 36d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This code is not thread safe. */ 37d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 38d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic uint64_t current_malloc_count = 0; 39d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic uint64_t malloc_number_to_fail = 0; 40d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic char failure_enabled = 0, abort_on_fail = 0; 41d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int in_call = 0; 42d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 43d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyextern "C" { 44d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* These are other names for the standard allocation functions. */ 45d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyextern void *__libc_malloc(size_t size); 46d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyextern void *__libc_calloc(size_t num_elems, size_t size); 47d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyextern void *__libc_realloc(void *ptr, size_t size); 48d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 49d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 50d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic void exit_handler(void) { 51d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (failure_enabled && current_malloc_count > malloc_number_to_fail) { 52d9e397b599b13d642138480a28c14db7a136bf0Adam Langley _exit(88); 53d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 54d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 55d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 56d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic void cpp_new_handler() { 57d9e397b599b13d642138480a28c14db7a136bf0Adam Langley // Return to try again. It won't fail a second time. 58d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return; 59d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 60d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 61d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* should_fail_allocation returns true if the current allocation should fail. */ 62d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int should_fail_allocation() { 63d9e397b599b13d642138480a28c14db7a136bf0Adam Langley static int init = 0; 64d9e397b599b13d642138480a28c14db7a136bf0Adam Langley char should_fail; 65d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 66d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (in_call) { 67d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 68d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 69d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 70d9e397b599b13d642138480a28c14db7a136bf0Adam Langley in_call = 1; 71d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 72d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!init) { 73d9e397b599b13d642138480a28c14db7a136bf0Adam Langley const char *env = getenv("MALLOC_NUMBER_TO_FAIL"); 74d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (env != NULL && env[0] != 0) { 75d9e397b599b13d642138480a28c14db7a136bf0Adam Langley char *endptr; 76d9e397b599b13d642138480a28c14db7a136bf0Adam Langley malloc_number_to_fail = strtoull(env, &endptr, 10); 77d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (*endptr == 0) { 78d9e397b599b13d642138480a28c14db7a136bf0Adam Langley failure_enabled = 1; 79d9e397b599b13d642138480a28c14db7a136bf0Adam Langley atexit(exit_handler); 80d9e397b599b13d642138480a28c14db7a136bf0Adam Langley std::set_new_handler(cpp_new_handler); 81d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 82d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 83d9e397b599b13d642138480a28c14db7a136bf0Adam Langley abort_on_fail = (NULL != getenv("MALLOC_ABORT_ON_FAIL")); 84d9e397b599b13d642138480a28c14db7a136bf0Adam Langley init = 1; 85d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 86d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 87d9e397b599b13d642138480a28c14db7a136bf0Adam Langley in_call = 0; 88d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 89d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!failure_enabled) { 90d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 91d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 92d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 93d9e397b599b13d642138480a28c14db7a136bf0Adam Langley should_fail = (current_malloc_count == malloc_number_to_fail); 94d9e397b599b13d642138480a28c14db7a136bf0Adam Langley current_malloc_count++; 95d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 96d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (should_fail && abort_on_fail) { 97d9e397b599b13d642138480a28c14db7a136bf0Adam Langley abort(); 98d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 99d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return should_fail; 100d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 101d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 102d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyextern "C" { 103d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 104d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid *malloc(size_t size) { 105d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (should_fail_allocation()) { 106d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 107d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 108d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 109d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return __libc_malloc(size); 110d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 111d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 112d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid *calloc(size_t num_elems, size_t size) { 113d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (should_fail_allocation()) { 114d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 115d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 116d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 117d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return __libc_calloc(num_elems, size); 118d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 119d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 120d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid *realloc(void *ptr, size_t size) { 121d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (should_fail_allocation()) { 122d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 123d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 124d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 125d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return __libc_realloc(ptr, size); 126d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 127d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 128d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} // extern "C" 129d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 130d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#endif /* defined(linux) && !ARM && !AARCH64 */ 131