malloc.cc revision f4e427204234da139fd0585def4b4e22502e33f0
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)
18f4e427204234da139fd0585def4b4e22502e33f0Adam Langley#if __has_feature(address_sanitizer) || __has_feature(memory_sanitizer)
19e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#define OPENSSL_ASAN
20e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#endif
21e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#endif
22e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
23f4e427204234da139fd0585def4b4e22502e33f0Adam Langley#if defined(__GLIBC__) && !defined(__UCLIBC__)
24f4e427204234da139fd0585def4b4e22502e33f0Adam Langley#define OPENSSL_GLIBC
25f4e427204234da139fd0585def4b4e22502e33f0Adam Langley#endif
26f4e427204234da139fd0585def4b4e22502e33f0Adam Langley
27d9e397b599b13d642138480a28c14db7a136bf0Adam Langley// This file isn't built on ARM or Aarch64 because we link statically in those
28f4e427204234da139fd0585def4b4e22502e33f0Adam Langley// builds and trying to override malloc in a static link doesn't work. It also
29f4e427204234da139fd0585def4b4e22502e33f0Adam Langley// requires glibc. It's also disabled on ASan builds as this interferes with
30f4e427204234da139fd0585def4b4e22502e33f0Adam Langley// ASan's malloc interceptor.
31e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley//
32f4e427204234da139fd0585def4b4e22502e33f0Adam Langley// TODO(davidben): See if this and ASan's and MSan's interceptors can be made to
33f4e427204234da139fd0585def4b4e22502e33f0Adam Langley// coexist.
34f4e427204234da139fd0585def4b4e22502e33f0Adam 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
145f4e427204234da139fd0585def4b4e22502e33f0Adam Langley#endif  /* defined(linux) && GLIBC && !ARM && !AARCH64 && !ASAN */
146