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 17e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#if defined(__has_feature) 1853b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley#if __has_feature(address_sanitizer) || __has_feature(memory_sanitizer) 19e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#define OPENSSL_ASAN 20e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#endif 21e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#endif 22e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 2353b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley#if defined(__GLIBC__) && !defined(__UCLIBC__) 2453b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley#define OPENSSL_GLIBC 2553b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley#endif 2653b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley 27d9e397b599b13d642138480a28c14db7a136bf0Adam Langley// This file isn't built on ARM or Aarch64 because we link statically in those 2853b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley// builds and trying to override malloc in a static link doesn't work. It also 2953b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley// requires glibc. It's also disabled on ASan builds as this interferes with 3053b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley// ASan's malloc interceptor. 31e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley// 3253b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley// TODO(davidben): See if this and ASan's and MSan's interceptors can be made to 3353b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley// coexist. 3453b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley#if defined(__linux__) && defined(OPENSSL_GLIBC) && !defined(OPENSSL_ARM) && \ 35e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley !defined(OPENSSL_AARCH64) && !defined(OPENSSL_ASAN) 36d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 37d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <stdint.h> 38e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include <stdio.h> 39d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <stdlib.h> 40d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <unistd.h> 41d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 42d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <new> 43d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 44d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 45d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* This file defines overrides for the standard allocation functions that allow 46d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * a given allocation to be made to fail for testing. If the program is run 47d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * with MALLOC_NUMBER_TO_FAIL set to a base-10 number then that allocation will 48d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * return NULL. If MALLOC_ABORT_ON_FAIL is also defined then the allocation 49d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * will abort() rather than return NULL. 50d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 51d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This code is not thread safe. */ 52d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 53d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic uint64_t current_malloc_count = 0; 54d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic uint64_t malloc_number_to_fail = 0; 55d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic char failure_enabled = 0, abort_on_fail = 0; 56d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int in_call = 0; 57d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 58d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyextern "C" { 59d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* These are other names for the standard allocation functions. */ 60d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyextern void *__libc_malloc(size_t size); 61d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyextern void *__libc_calloc(size_t num_elems, size_t size); 62d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyextern void *__libc_realloc(void *ptr, size_t size); 63d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 64d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 65d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic void exit_handler(void) { 66d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (failure_enabled && current_malloc_count > malloc_number_to_fail) { 67d9e397b599b13d642138480a28c14db7a136bf0Adam Langley _exit(88); 68d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 69d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 70d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 71d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic void cpp_new_handler() { 72d9e397b599b13d642138480a28c14db7a136bf0Adam Langley // Return to try again. It won't fail a second time. 73d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return; 74d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 75d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 76d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* should_fail_allocation returns true if the current allocation should fail. */ 77d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int should_fail_allocation() { 78d9e397b599b13d642138480a28c14db7a136bf0Adam Langley static int init = 0; 79d9e397b599b13d642138480a28c14db7a136bf0Adam Langley char should_fail; 80d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 81d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (in_call) { 82d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 83d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 84d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 85d9e397b599b13d642138480a28c14db7a136bf0Adam Langley in_call = 1; 86d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 87d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!init) { 88d9e397b599b13d642138480a28c14db7a136bf0Adam Langley const char *env = getenv("MALLOC_NUMBER_TO_FAIL"); 89d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (env != NULL && env[0] != 0) { 90d9e397b599b13d642138480a28c14db7a136bf0Adam Langley char *endptr; 91d9e397b599b13d642138480a28c14db7a136bf0Adam Langley malloc_number_to_fail = strtoull(env, &endptr, 10); 92d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (*endptr == 0) { 93d9e397b599b13d642138480a28c14db7a136bf0Adam Langley failure_enabled = 1; 94d9e397b599b13d642138480a28c14db7a136bf0Adam Langley atexit(exit_handler); 95d9e397b599b13d642138480a28c14db7a136bf0Adam Langley std::set_new_handler(cpp_new_handler); 96d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 97d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 98d9e397b599b13d642138480a28c14db7a136bf0Adam Langley abort_on_fail = (NULL != getenv("MALLOC_ABORT_ON_FAIL")); 99d9e397b599b13d642138480a28c14db7a136bf0Adam Langley init = 1; 100d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 101d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 102d9e397b599b13d642138480a28c14db7a136bf0Adam Langley in_call = 0; 103d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 104d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!failure_enabled) { 105d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 106d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 107d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 108d9e397b599b13d642138480a28c14db7a136bf0Adam Langley should_fail = (current_malloc_count == malloc_number_to_fail); 109d9e397b599b13d642138480a28c14db7a136bf0Adam Langley current_malloc_count++; 110d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 111d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (should_fail && abort_on_fail) { 112d9e397b599b13d642138480a28c14db7a136bf0Adam Langley abort(); 113d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 114d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return should_fail; 115d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 116d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 117d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyextern "C" { 118d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 119d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid *malloc(size_t size) { 120d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (should_fail_allocation()) { 121d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 122d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 123d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 124d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return __libc_malloc(size); 125d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 126d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 127d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid *calloc(size_t num_elems, size_t size) { 128d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (should_fail_allocation()) { 129d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 130d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 131d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 132d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return __libc_calloc(num_elems, size); 133d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 134d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 135d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid *realloc(void *ptr, size_t size) { 136d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (should_fail_allocation()) { 137d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 138d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 139d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 140d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return __libc_realloc(ptr, size); 141d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 142d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 143d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} // extern "C" 144d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 14553b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley#endif /* defined(linux) && GLIBC && !ARM && !AARCH64 && !ASAN */ 146