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 17f4e427204234da139fd0585def4b4e22502e33f0Adam Langley#if defined(__GLIBC__) && !defined(__UCLIBC__) 18f4e427204234da139fd0585def4b4e22502e33f0Adam Langley#define OPENSSL_GLIBC 19f4e427204234da139fd0585def4b4e22502e33f0Adam Langley#endif 20f4e427204234da139fd0585def4b4e22502e33f0Adam Langley 21d9e397b599b13d642138480a28c14db7a136bf0Adam Langley// This file isn't built on ARM or Aarch64 because we link statically in those 22f4e427204234da139fd0585def4b4e22502e33f0Adam Langley// builds and trying to override malloc in a static link doesn't work. It also 2395add82835138f09cf7bb4a51c04c6320c241674David Benjamin// requires glibc. It's also disabled on ASan builds as this interferes with 2495add82835138f09cf7bb4a51c04c6320c241674David Benjamin// ASan's malloc interceptor. 2595add82835138f09cf7bb4a51c04c6320c241674David Benjamin// 2695add82835138f09cf7bb4a51c04c6320c241674David Benjamin// TODO(davidben): See if this and ASan's and MSan's interceptors can be made to 2795add82835138f09cf7bb4a51c04c6320c241674David Benjamin// coexist. 28f4e427204234da139fd0585def4b4e22502e33f0Adam Langley#if defined(__linux__) && defined(OPENSSL_GLIBC) && !defined(OPENSSL_ARM) && \ 298ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan !defined(OPENSSL_AARCH64) && !defined(OPENSSL_ASAN) && \ 308ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan !defined(OPENSSL_MSAN) 31d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 32b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root#include <errno.h> 33b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root#include <signal.h> 34d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <stdint.h> 35e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include <stdio.h> 36d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <stdlib.h> 37d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <unistd.h> 38d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 39d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <new> 40d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 41d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 4295add82835138f09cf7bb4a51c04c6320c241674David Benjamin// This file defines overrides for the standard allocation functions that allow 4395add82835138f09cf7bb4a51c04c6320c241674David Benjamin// a given allocation to be made to fail for testing. If the program is run 4495add82835138f09cf7bb4a51c04c6320c241674David Benjamin// with MALLOC_NUMBER_TO_FAIL set to a base-10 number then that allocation will 4595add82835138f09cf7bb4a51c04c6320c241674David Benjamin// return NULL. If MALLOC_BREAK_ON_FAIL is also defined then the allocation 4695add82835138f09cf7bb4a51c04c6320c241674David Benjamin// will signal SIGTRAP rather than return NULL. 4795add82835138f09cf7bb4a51c04c6320c241674David Benjamin// 4895add82835138f09cf7bb4a51c04c6320c241674David Benjamin// This code is not thread safe. 49d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 50d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic uint64_t current_malloc_count = 0; 51d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic uint64_t malloc_number_to_fail = 0; 5295add82835138f09cf7bb4a51c04c6320c241674David Benjaminstatic bool failure_enabled = false, break_on_fail = false, in_call = false; 53d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 54d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyextern "C" { 5595add82835138f09cf7bb4a51c04c6320c241674David Benjamin// These are other names for the standard allocation functions. 5695add82835138f09cf7bb4a51c04c6320c241674David Benjaminextern void *__libc_malloc(size_t size); 5795add82835138f09cf7bb4a51c04c6320c241674David Benjaminextern void *__libc_calloc(size_t num_elems, size_t size); 5895add82835138f09cf7bb4a51c04c6320c241674David Benjaminextern void *__libc_realloc(void *ptr, size_t size); 59d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 60d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 61d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic void exit_handler(void) { 62d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (failure_enabled && current_malloc_count > malloc_number_to_fail) { 63d9e397b599b13d642138480a28c14db7a136bf0Adam Langley _exit(88); 64d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 65d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 66d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 67d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic void cpp_new_handler() { 68d9e397b599b13d642138480a28c14db7a136bf0Adam Langley // Return to try again. It won't fail a second time. 69d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return; 70d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 71d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 7295add82835138f09cf7bb4a51c04c6320c241674David Benjamin// should_fail_allocation returns true if the current allocation should fail. 7395add82835138f09cf7bb4a51c04c6320c241674David Benjaminstatic bool should_fail_allocation() { 7495add82835138f09cf7bb4a51c04c6320c241674David Benjamin static bool init = false; 75d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 76d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (in_call) { 7795add82835138f09cf7bb4a51c04c6320c241674David Benjamin return false; 78d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 79d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 8095add82835138f09cf7bb4a51c04c6320c241674David Benjamin in_call = true; 81d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 82d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!init) { 83d9e397b599b13d642138480a28c14db7a136bf0Adam Langley const char *env = getenv("MALLOC_NUMBER_TO_FAIL"); 84d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (env != NULL && env[0] != 0) { 85d9e397b599b13d642138480a28c14db7a136bf0Adam Langley char *endptr; 86d9e397b599b13d642138480a28c14db7a136bf0Adam Langley malloc_number_to_fail = strtoull(env, &endptr, 10); 87d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (*endptr == 0) { 8895add82835138f09cf7bb4a51c04c6320c241674David Benjamin failure_enabled = true; 89d9e397b599b13d642138480a28c14db7a136bf0Adam Langley atexit(exit_handler); 90d9e397b599b13d642138480a28c14db7a136bf0Adam Langley std::set_new_handler(cpp_new_handler); 91d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 92d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 93b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root break_on_fail = (NULL != getenv("MALLOC_BREAK_ON_FAIL")); 9495add82835138f09cf7bb4a51c04c6320c241674David Benjamin init = true; 95d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 96d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 9795add82835138f09cf7bb4a51c04c6320c241674David Benjamin in_call = false; 98d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 99d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!failure_enabled) { 10095add82835138f09cf7bb4a51c04c6320c241674David Benjamin return false; 101d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 102d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 10395add82835138f09cf7bb4a51c04c6320c241674David Benjamin bool should_fail = (current_malloc_count == malloc_number_to_fail); 104d9e397b599b13d642138480a28c14db7a136bf0Adam Langley current_malloc_count++; 105d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 106b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root if (should_fail && break_on_fail) { 107b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root raise(SIGTRAP); 108d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 109d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return should_fail; 110d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 111d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 112d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyextern "C" { 113d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 114d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid *malloc(size_t size) { 115d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (should_fail_allocation()) { 116b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root errno = ENOMEM; 117d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 118d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 119d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 12095add82835138f09cf7bb4a51c04c6320c241674David Benjamin return __libc_malloc(size); 121d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 122d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 123d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid *calloc(size_t num_elems, size_t size) { 124d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (should_fail_allocation()) { 125b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root errno = ENOMEM; 126d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 127d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 128d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 12995add82835138f09cf7bb4a51c04c6320c241674David Benjamin return __libc_calloc(num_elems, size); 130d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 131d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 132d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid *realloc(void *ptr, size_t size) { 133d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (should_fail_allocation()) { 134b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root errno = ENOMEM; 135d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 136d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 137d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 13895add82835138f09cf7bb4a51c04c6320c241674David Benjamin return __libc_realloc(ptr, size); 139d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 140d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 141d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} // extern "C" 142d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 143f4e427204234da139fd0585def4b4e22502e33f0Adam Langley#endif /* defined(linux) && GLIBC && !ARM && !AARCH64 && !ASAN */ 144