malloc.c (6627B)
1 /* Copyright (c) 2003, Roger Dingledine 2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. 3 * Copyright (c) 2007-2021, The Tor Project, Inc. */ 4 /* See LICENSE for licensing information */ 5 6 /** 7 * \file malloc.c 8 * \brief Wrappers for C malloc code, and replacements for items that 9 * may be missing. 10 **/ 11 12 #include "orconfig.h" 13 14 #include <stdlib.h> 15 #include <string.h> 16 17 #include "lib/testsupport/testsupport.h" 18 #define UTIL_MALLOC_PRIVATE 19 #include "lib/malloc/malloc.h" 20 #include "lib/cc/torint.h" 21 #include "lib/err/torerr.h" 22 23 #ifdef __clang_analyzer__ 24 #undef MALLOC_ZERO_WORKS 25 #endif 26 27 /** Allocate a chunk of <b>size</b> bytes of memory, and return a pointer to 28 * result. On error, log and terminate the process. (Same as malloc(size), 29 * but never returns NULL.) 30 */ 31 void * 32 tor_malloc_(size_t size) 33 { 34 void *result; 35 36 raw_assert(size < SIZE_T_CEILING); 37 38 #ifndef MALLOC_ZERO_WORKS 39 /* Some libc mallocs don't work when size==0. Override them. */ 40 if (size==0) { 41 size=1; 42 } 43 #endif /* !defined(MALLOC_ZERO_WORKS) */ 44 45 result = raw_malloc(size); 46 47 if (PREDICT_UNLIKELY(result == NULL)) { 48 /* LCOV_EXCL_START */ 49 /* If these functions die within a worker process, they won't call 50 * spawn_exit, but that's ok, since the parent will run out of memory soon 51 * anyway. */ 52 raw_assert_unreached_msg("Out of memory on malloc(). Dying."); 53 /* LCOV_EXCL_STOP */ 54 } 55 return result; 56 } 57 58 /** Allocate a chunk of <b>size</b> bytes of memory, fill the memory with 59 * zero bytes, and return a pointer to the result. Log and terminate 60 * the process on error. (Same as calloc(size,1), but never returns NULL.) 61 */ 62 void * 63 tor_malloc_zero_(size_t size) 64 { 65 /* You may ask yourself, "wouldn't it be smart to use calloc instead of 66 * malloc+memset? Perhaps libc's calloc knows some nifty optimization trick 67 * we don't!" Indeed it does, but its optimizations are only a big win when 68 * we're allocating something very big (it knows if it just got the memory 69 * from the OS in a pre-zeroed state). We don't want to use tor_malloc_zero 70 * for big stuff, so we don't bother with calloc. */ 71 void *result = tor_malloc_(size); 72 memset(result, 0, size); 73 return result; 74 } 75 76 /* The square root of SIZE_MAX + 1. If a is less than this, and b is less 77 * than this, then a*b is less than SIZE_MAX. (For example, if size_t is 78 * 32 bits, then SIZE_MAX is 0xffffffff and this value is 0x10000. If a and 79 * b are less than this, then their product is at most (65535*65535) == 80 * 0xfffe0001. */ 81 #define SQRT_SIZE_MAX_P1 (((size_t)1) << (sizeof(size_t)*4)) 82 83 /** Return non-zero if and only if the product of the arguments is exact, 84 * and cannot overflow. */ 85 STATIC int 86 size_mul_check(const size_t x, const size_t y) 87 { 88 /* This first check is equivalent to 89 (x < SQRT_SIZE_MAX_P1 && y < SQRT_SIZE_MAX_P1) 90 91 Rationale: if either one of x or y is >= SQRT_SIZE_MAX_P1, then it 92 will have some bit set in its most significant half. 93 */ 94 return ((x|y) < SQRT_SIZE_MAX_P1 || 95 y == 0 || 96 x <= SIZE_MAX / y); 97 } 98 99 /** Allocate a chunk of <b>nmemb</b>*<b>size</b> bytes of memory, fill 100 * the memory with zero bytes, and return a pointer to the result. 101 * Log and terminate the process on error. (Same as 102 * calloc(<b>nmemb</b>,<b>size</b>), but never returns NULL.) 103 * The second argument (<b>size</b>) should preferably be non-zero 104 * and a compile-time constant. 105 */ 106 void * 107 tor_calloc_(size_t nmemb, size_t size) 108 { 109 raw_assert(size_mul_check(nmemb, size)); 110 return tor_malloc_zero_((nmemb * size)); 111 } 112 113 /** Change the size of the memory block pointed to by <b>ptr</b> to <b>size</b> 114 * bytes long; return the new memory block. On error, log and 115 * terminate. (Like realloc(ptr,size), but never returns NULL.) 116 */ 117 void * 118 tor_realloc_(void *ptr, size_t size) 119 { 120 void *result; 121 122 raw_assert(size < SIZE_T_CEILING); 123 124 #ifndef MALLOC_ZERO_WORKS 125 /* Some libc mallocs don't work when size==0. Override them. */ 126 if (size==0) { 127 size=1; 128 } 129 #endif /* !defined(MALLOC_ZERO_WORKS) */ 130 131 result = raw_realloc(ptr, size); 132 133 if (PREDICT_UNLIKELY(result == NULL)) { 134 /* LCOV_EXCL_START */ 135 raw_assert_unreached_msg("Out of memory on realloc(). Dying."); 136 /* LCOV_EXCL_STOP */ 137 } 138 return result; 139 } 140 141 /** 142 * Try to realloc <b>ptr</b> so that it takes up sz1 * sz2 bytes. Check for 143 * overflow. Unlike other allocation functions, return NULL on overflow. 144 */ 145 void * 146 tor_reallocarray_(void *ptr, size_t sz1, size_t sz2) 147 { 148 /* XXXX we can make this return 0, but we would need to check all the 149 * reallocarray users. */ 150 raw_assert(size_mul_check(sz1, sz2)); 151 152 return tor_realloc(ptr, (sz1 * sz2)); 153 } 154 155 /** Return a newly allocated copy of the NUL-terminated string s. On 156 * error, log and terminate. (Like strdup(s), but never returns 157 * NULL.) 158 */ 159 char * 160 tor_strdup_(const char *s) 161 { 162 char *duplicate; 163 raw_assert(s); 164 165 duplicate = raw_strdup(s); 166 167 if (PREDICT_UNLIKELY(duplicate == NULL)) { 168 /* LCOV_EXCL_START */ 169 raw_assert_unreached_msg("Out of memory on strdup(). Dying."); 170 /* LCOV_EXCL_STOP */ 171 } 172 return duplicate; 173 } 174 175 /** Allocate and return a new string containing the first <b>n</b> 176 * characters of <b>s</b>. If <b>s</b> is longer than <b>n</b> 177 * characters, only the first <b>n</b> are copied. The result is 178 * always NUL-terminated. (Like strndup(s,n), but never returns 179 * NULL.) 180 */ 181 char * 182 tor_strndup_(const char *s, size_t n) 183 { 184 char *duplicate; 185 raw_assert(s); 186 raw_assert(n < SIZE_T_CEILING); 187 duplicate = tor_malloc_((n+1)); 188 /* Performance note: Ordinarily we prefer strlcpy to strncpy. But 189 * this function gets called a whole lot, and platform strncpy is 190 * much faster than strlcpy when strlen(s) is much longer than n. 191 */ 192 strncpy(duplicate, s, n); 193 duplicate[n]='\0'; 194 return duplicate; 195 } 196 197 /** Allocate a chunk of <b>len</b> bytes, with the same contents as the 198 * <b>len</b> bytes starting at <b>mem</b>. */ 199 void * 200 tor_memdup_(const void *mem, size_t len) 201 { 202 char *duplicate; 203 raw_assert(len < SIZE_T_CEILING); 204 raw_assert(mem); 205 duplicate = tor_malloc_(len); 206 memcpy(duplicate, mem, len); 207 return duplicate; 208 } 209 210 /** As tor_memdup(), but add an extra 0 byte at the end of the resulting 211 * memory. */ 212 void * 213 tor_memdup_nulterm_(const void *mem, size_t len) 214 { 215 char *duplicate; 216 raw_assert(len < SIZE_T_CEILING+1); 217 raw_assert(mem); 218 duplicate = tor_malloc_(len+1); 219 memcpy(duplicate, mem, len); 220 duplicate[len] = '\0'; 221 return duplicate; 222 } 223 224 /** Helper for places that need to take a function pointer to the right 225 * spelling of "free()". */ 226 void 227 tor_free_(void *mem) 228 { 229 tor_free(mem); 230 }