mem.c
Go to the documentation of this file.
1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young (eay@cryptsoft.com).
6  * The implementation was written so as to conform with Netscapes SSL.
7  *
8  * This library is free for commercial and non-commercial use as long as
9  * the following conditions are aheared to. The following conditions
10  * apply to all code found in this distribution, be it the RC4, RSA,
11  * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12  * included with this distribution is covered by the same copyright terms
13  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14  *
15  * Copyright remains Eric Young's, and as such any Copyright notices in
16  * the code are not to be removed.
17  * If this package is used in a product, Eric Young should be given attribution
18  * as the author of the parts of the library used.
19  * This can be in the form of a textual message at program startup or
20  * in documentation (online or textual) provided with the package.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the copyright
26  * notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  * notice, this list of conditions and the following disclaimer in the
29  * documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  * must display the following acknowledgement:
32  * "This product includes cryptographic software written by
33  * Eric Young (eay@cryptsoft.com)"
34  * The word 'cryptographic' can be left out if the rouines from the library
35  * being used are not cryptographic related :-).
36  * 4. If you include any Windows specific code (or a derivative thereof) from
37  * the apps directory (application code) you must include an acknowledgement:
38  * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  *
52  * The licence and distribution terms for any publically available version or
53  * derivative of this code cannot be changed. i.e. this code cannot simply be
54  * copied and put under another distribution licence
55  * [including the GNU Public Licence.] */
56 
57 #include <openssl/mem.h>
58 
59 #include <assert.h>
60 #include <stdarg.h>
61 #include <stdio.h>
62 
63 #include <openssl/err.h>
64 
65 #if defined(OPENSSL_WINDOWS)
67 #include <windows.h>
69 #endif
70 
71 #include "internal.h"
72 
73 
74 #define OPENSSL_MALLOC_PREFIX 8
76  "size_t too large");
77 
78 #if defined(OPENSSL_ASAN)
79 void __asan_poison_memory_region(const volatile void *addr, size_t size);
80 void __asan_unpoison_memory_region(const volatile void *addr, size_t size);
81 #else
82 static void __asan_poison_memory_region(const void *addr, size_t size) {}
83 static void __asan_unpoison_memory_region(const void *addr, size_t size) {}
84 #endif
85 
86 // Windows doesn't really support weak symbols as of May 2019, and Clang on
87 // Windows will emit strong symbols instead. See
88 // https://bugs.llvm.org/show_bug.cgi?id=37598
89 #if defined(__ELF__) && defined(__GNUC__)
90 #define WEAK_SYMBOL_FUNC(rettype, name, args) \
91  rettype name args __attribute__((weak));
92 #else
93 #define WEAK_SYMBOL_FUNC(rettype, name, args) static rettype(*name) args = NULL;
94 #endif
95 
96 // sdallocx is a sized |free| function. By passing the size (which we happen to
97 // always know in BoringSSL), the malloc implementation can save work. We cannot
98 // depend on |sdallocx| being available, however, so it's a weak symbol.
99 //
100 // This will always be safe, but will only be overridden if the malloc
101 // implementation is statically linked with BoringSSL. So, if |sdallocx| is
102 // provided in, say, libc.so, we still won't use it because that's dynamically
103 // linked. This isn't an ideal result, but its helps in some cases.
104 WEAK_SYMBOL_FUNC(void, sdallocx, (void *ptr, size_t size, int flags));
105 
106 // The following three functions can be defined to override default heap
107 // allocation and freeing. If defined, it is the responsibility of
108 // |OPENSSL_memory_free| to zero out the memory before returning it to the
109 // system. |OPENSSL_memory_free| will not be passed NULL pointers.
110 //
111 // WARNING: These functions are called on every allocation and free in
112 // BoringSSL across the entire process. They may be called by any code in the
113 // process which calls BoringSSL, including in process initializers and thread
114 // destructors. When called, BoringSSL may hold pthreads locks. Any other code
115 // in the process which, directly or indirectly, calls BoringSSL may be on the
116 // call stack and may itself be using arbitrary synchronization primitives.
117 //
118 // As a result, these functions may not have the usual programming environment
119 // available to most C or C++ code. In particular, they may not call into
120 // BoringSSL, or any library which depends on BoringSSL. Any synchronization
121 // primitives used must tolerate every other synchronization primitive linked
122 // into the process, including pthreads locks. Failing to meet these constraints
123 // may result in deadlocks, crashes, or memory corruption.
124 WEAK_SYMBOL_FUNC(void*, OPENSSL_memory_alloc, (size_t size));
125 WEAK_SYMBOL_FUNC(void, OPENSSL_memory_free, (void *ptr));
126 WEAK_SYMBOL_FUNC(size_t, OPENSSL_memory_get_size, (void *ptr));
127 
128 // kBoringSSLBinaryTag is a distinctive byte sequence to identify binaries that
129 // are linking in BoringSSL and, roughly, what version they are using.
130 static const uint8_t kBoringSSLBinaryTag[18] = {
131  // 16 bytes of magic tag.
132  0x8c, 0x62, 0x20, 0x0b, 0xd2, 0xa0, 0x72, 0x58,
133  0x44, 0xa8, 0x96, 0x69, 0xad, 0x55, 0x7e, 0xec,
134  // Current source iteration. Incremented ~monthly.
135  2, 0,
136 };
137 
138 void *OPENSSL_malloc(size_t size) {
139  if (OPENSSL_memory_alloc != NULL) {
140  assert(OPENSSL_memory_free != NULL);
141  assert(OPENSSL_memory_get_size != NULL);
142  return OPENSSL_memory_alloc(size);
143  }
144 
145  if (size + OPENSSL_MALLOC_PREFIX < size) {
146  // |OPENSSL_malloc| is a central function in BoringSSL thus a reference to
147  // |kBoringSSLBinaryTag| is created here so that the tag isn't discarded by
148  // the linker. The following is sufficient to stop GCC, Clang, and MSVC
149  // optimising away the reference at the time of writing. Since this
150  // probably results in an actual memory reference, it is put in this very
151  // rare code path.
152  uint8_t unused = *(volatile uint8_t *)kBoringSSLBinaryTag;
153  (void) unused;
154  return NULL;
155  }
156 
157  void *ptr = malloc(size + OPENSSL_MALLOC_PREFIX);
158  if (ptr == NULL) {
159  return NULL;
160  }
161 
162  *(size_t *)ptr = size;
163 
165  return ((uint8_t *)ptr) + OPENSSL_MALLOC_PREFIX;
166 }
167 
168 void OPENSSL_free(void *orig_ptr) {
169  if (orig_ptr == NULL) {
170  return;
171  }
172 
173  if (OPENSSL_memory_free != NULL) {
174  OPENSSL_memory_free(orig_ptr);
175  return;
176  }
177 
178  void *ptr = ((uint8_t *)orig_ptr) - OPENSSL_MALLOC_PREFIX;
180 
181  size_t size = *(size_t *)ptr;
183  if (sdallocx) {
184  sdallocx(ptr, size + OPENSSL_MALLOC_PREFIX, 0 /* flags */);
185  } else {
186  free(ptr);
187  }
188 }
189 
190 void *OPENSSL_realloc(void *orig_ptr, size_t new_size) {
191  if (orig_ptr == NULL) {
192  return OPENSSL_malloc(new_size);
193  }
194 
195  size_t old_size;
196  if (OPENSSL_memory_get_size != NULL) {
197  old_size = OPENSSL_memory_get_size(orig_ptr);
198  } else {
199  void *ptr = ((uint8_t *)orig_ptr) - OPENSSL_MALLOC_PREFIX;
201  old_size = *(size_t *)ptr;
203  }
204 
205  void *ret = OPENSSL_malloc(new_size);
206  if (ret == NULL) {
207  return NULL;
208  }
209 
210  size_t to_copy = new_size;
211  if (old_size < to_copy) {
212  to_copy = old_size;
213  }
214 
215  memcpy(ret, orig_ptr, to_copy);
216  OPENSSL_free(orig_ptr);
217 
218  return ret;
219 }
220 
221 void OPENSSL_cleanse(void *ptr, size_t len) {
222 #if defined(OPENSSL_WINDOWS)
223  SecureZeroMemory(ptr, len);
224 #else
225  OPENSSL_memset(ptr, 0, len);
226 
227 #if !defined(OPENSSL_NO_ASM)
228  /* As best as we can tell, this is sufficient to break any optimisations that
229  might try to eliminate "superfluous" memsets. If there's an easy way to
230  detect memset_s, it would be better to use that. */
231  __asm__ __volatile__("" : : "r"(ptr) : "memory");
232 #endif
233 #endif // !OPENSSL_NO_ASM
234 }
235 
236 void OPENSSL_clear_free(void *ptr, size_t unused) {
237  OPENSSL_free(ptr);
238 }
239 
240 int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len) {
241  const uint8_t *a = in_a;
242  const uint8_t *b = in_b;
243  uint8_t x = 0;
244 
245  for (size_t i = 0; i < len; i++) {
246  x |= a[i] ^ b[i];
247  }
248 
249  return x;
250 }
251 
252 uint32_t OPENSSL_hash32(const void *ptr, size_t len) {
253  // These are the FNV-1a parameters for 32 bits.
254  static const uint32_t kPrime = 16777619u;
255  static const uint32_t kOffsetBasis = 2166136261u;
256 
257  const uint8_t *in = ptr;
258  uint32_t h = kOffsetBasis;
259 
260  for (size_t i = 0; i < len; i++) {
261  h ^= in[i];
262  h *= kPrime;
263  }
264 
265  return h;
266 }
267 
268 uint32_t OPENSSL_strhash(const char *s) { return OPENSSL_hash32(s, strlen(s)); }
269 
270 size_t OPENSSL_strnlen(const char *s, size_t len) {
271  for (size_t i = 0; i < len; i++) {
272  if (s[i] == 0) {
273  return i;
274  }
275  }
276 
277  return len;
278 }
279 
280 char *OPENSSL_strdup(const char *s) {
281  if (s == NULL) {
282  return NULL;
283  }
284  const size_t len = strlen(s) + 1;
285  char *ret = OPENSSL_malloc(len);
286  if (ret == NULL) {
287  return NULL;
288  }
289  OPENSSL_memcpy(ret, s, len);
290  return ret;
291 }
292 
293 int OPENSSL_tolower(int c) {
294  if (c >= 'A' && c <= 'Z') {
295  return c + ('a' - 'A');
296  }
297  return c;
298 }
299 
300 int OPENSSL_strcasecmp(const char *a, const char *b) {
301  for (size_t i = 0;; i++) {
302  const int aa = OPENSSL_tolower(a[i]);
303  const int bb = OPENSSL_tolower(b[i]);
304 
305  if (aa < bb) {
306  return -1;
307  } else if (aa > bb) {
308  return 1;
309  } else if (aa == 0) {
310  return 0;
311  }
312  }
313 }
314 
315 int OPENSSL_strncasecmp(const char *a, const char *b, size_t n) {
316  for (size_t i = 0; i < n; i++) {
317  const int aa = OPENSSL_tolower(a[i]);
318  const int bb = OPENSSL_tolower(b[i]);
319 
320  if (aa < bb) {
321  return -1;
322  } else if (aa > bb) {
323  return 1;
324  } else if (aa == 0) {
325  return 0;
326  }
327  }
328 
329  return 0;
330 }
331 
332 int BIO_snprintf(char *buf, size_t n, const char *format, ...) {
333  va_list args;
334  va_start(args, format);
335  int ret = BIO_vsnprintf(buf, n, format, args);
336  va_end(args);
337  return ret;
338 }
339 
340 int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) {
341  return vsnprintf(buf, n, format, args);
342 }
343 
344 char *OPENSSL_strndup(const char *str, size_t size) {
346 
347  size_t alloc_size = size + 1;
348  if (alloc_size < size) {
349  // overflow
351  return NULL;
352  }
353  char *ret = OPENSSL_malloc(alloc_size);
354  if (ret == NULL) {
356  return NULL;
357  }
358 
360  ret[size] = '\0';
361  return ret;
362 }
363 
364 size_t OPENSSL_strlcpy(char *dst, const char *src, size_t dst_size) {
365  size_t l = 0;
366 
367  for (; dst_size > 1 && *src; dst_size--) {
368  *dst++ = *src++;
369  l++;
370  }
371 
372  if (dst_size) {
373  *dst = 0;
374  }
375 
376  return l + strlen(src);
377 }
378 
379 size_t OPENSSL_strlcat(char *dst, const char *src, size_t dst_size) {
380  size_t l = 0;
381  for (; dst_size > 0 && *dst; dst_size--, dst++) {
382  l++;
383  }
384  return l + OPENSSL_strlcpy(dst, src, dst_size);
385 }
386 
387 void *OPENSSL_memdup(const void *data, size_t size) {
388  if (size == 0) {
389  return NULL;
390  }
391 
392  void *ret = OPENSSL_malloc(size);
393  if (ret == NULL) {
395  return NULL;
396  }
397 
399  return ret;
400 }
401 
402 void *CRYPTO_malloc(size_t size, const char *file, int line) {
403  return OPENSSL_malloc(size);
404 }
405 
406 void *CRYPTO_realloc(void *ptr, size_t new_size, const char *file, int line) {
407  return OPENSSL_realloc(ptr, new_size);
408 }
409 
410 void CRYPTO_free(void *ptr, const char *file, int line) { OPENSSL_free(ptr); }
xds_interop_client.str
str
Definition: xds_interop_client.py:487
ptr
char * ptr
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:45
dst
static const char dst[]
Definition: test-fs-copyfile.c:37
vsnprintf
int __cdecl vsnprintf(char *buffer, size_t count, const char *format, va_list argptr)
Definition: libc.cpp:135
http2_test_server.format
format
Definition: http2_test_server.py:118
CRYPTO_malloc
void * CRYPTO_malloc(size_t size, const char *file, int line)
Definition: mem.c:402
OPENSSL_strhash
uint32_t OPENSSL_strhash(const char *s)
Definition: mem.c:268
OPENSSL_strndup
char * OPENSSL_strndup(const char *str, size_t size)
Definition: mem.c:344
kBoringSSLBinaryTag
static const uint8_t kBoringSSLBinaryTag[18]
Definition: mem.c:130
OPENSSL_free
void OPENSSL_free(void *orig_ptr)
Definition: mem.c:168
OPENSSL_strnlen
size_t OPENSSL_strnlen(const char *s, size_t len)
Definition: mem.c:270
BIO_snprintf
int BIO_snprintf(char *buf, size_t n, const char *format,...)
Definition: mem.c:332
check_version.warning
string warning
Definition: check_version.py:46
OPENSSL_PUT_ERROR
#define OPENSSL_PUT_ERROR(library, reason)
Definition: err.h:423
internal.h
OPENSSL_tolower
int OPENSSL_tolower(int c)
Definition: mem.c:293
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
OPENSSL_malloc
void * OPENSSL_malloc(size_t size)
Definition: mem.c:138
binary_size.new_size
def new_size
Definition: binary_size.py:124
file
Definition: bloaty/third_party/zlib/examples/gzappend.c:170
u
OPENSSL_EXPORT pem_password_cb void * u
Definition: pem.h:351
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
OPENSSL_realloc
void * OPENSSL_realloc(void *orig_ptr, size_t new_size)
Definition: mem.c:190
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
OPENSSL_strdup
char * OPENSSL_strdup(const char *s)
Definition: mem.c:280
OPENSSL_clear_free
void OPENSSL_clear_free(void *ptr, size_t unused)
Definition: mem.c:236
OPENSSL_memset
static void * OPENSSL_memset(void *dst, int c, size_t n)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:835
CRYPTO_memcmp
int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len)
Definition: mem.c:240
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
in
const char * in
Definition: third_party/abseil-cpp/absl/strings/internal/str_format/parser_test.cc:391
BIO_vsnprintf
int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
Definition: mem.c:340
c
void c(T a)
Definition: miscompile_with_no_unique_address_test.cc:40
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
WEAK_SYMBOL_FUNC
#define WEAK_SYMBOL_FUNC(rettype, name, args)
Definition: mem.c:93
OPENSSL_strncasecmp
int OPENSSL_strncasecmp(const char *a, const char *b, size_t n)
Definition: mem.c:315
OPENSSL_memcpy
static void * OPENSSL_memcpy(void *dst, const void *src, size_t n)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:819
err.h
OPENSSL_MSVC_PRAGMA
OPENSSL_MSVC_PRAGMA(warning(disable:4702))
Definition: e_aes.c:69
OPENSSL_cleanse
void OPENSSL_cleanse(void *ptr, size_t len)
Definition: mem.c:221
x
int x
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3610
data
char data[kBufferLength]
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1006
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
push
int push(void *desc, unsigned char *buf, unsigned len)
Definition: bloaty/third_party/zlib/test/infcover.c:463
OPENSSL_hash32
uint32_t OPENSSL_hash32(const void *ptr, size_t len)
Definition: mem.c:252
__asan_unpoison_memory_region
static void __asan_unpoison_memory_region(const void *addr, size_t size)
Definition: mem.c:83
OPENSSL_MALLOC_PREFIX
#define OPENSSL_MALLOC_PREFIX
Definition: mem.c:74
absl::flags_internal
Definition: abseil-cpp/absl/flags/commandlineflag.h:40
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
OPENSSL_strcasecmp
int OPENSSL_strcasecmp(const char *a, const char *b)
Definition: mem.c:300
regen-readme.line
line
Definition: regen-readme.py:30
CRYPTO_realloc
void * CRYPTO_realloc(void *ptr, size_t new_size, const char *file, int line)
Definition: mem.c:406
CRYPTO_free
void CRYPTO_free(void *ptr, const char *file, int line)
Definition: mem.c:410
mem.h
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
run_grpclb_interop_tests.l
dictionary l
Definition: run_grpclb_interop_tests.py:410
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
__asan_poison_memory_region
static void __asan_poison_memory_region(const void *addr, size_t size)
Definition: mem.c:82
OPENSSL_memdup
void * OPENSSL_memdup(const void *data, size_t size)
Definition: mem.c:387
addr
struct sockaddr_in addr
Definition: libuv/docs/code/tcp-echo-server/main.c:10
OPENSSL_STATIC_ASSERT
OPENSSL_STATIC_ASSERT(OPENSSL_MALLOC_PREFIX >=sizeof(size_t), "size_t too large")
binary_size.old_size
old_size
Definition: binary_size.py:125
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
OPENSSL_strlcpy
size_t OPENSSL_strlcpy(char *dst, const char *src, size_t dst_size)
Definition: mem.c:364
ERR_R_MALLOC_FAILURE
#define ERR_R_MALLOC_FAILURE
Definition: err.h:371
OPENSSL_strlcat
size_t OPENSSL_strlcat(char *dst, const char *src, size_t dst_size)
Definition: mem.c:379


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:23