VirtualBox

source: vbox/trunk/src/libs/openssl-3.1.0/crypto/mem_sec.c@ 100908

最後變更 在這個檔案從100908是 99366,由 vboxsync 提交於 21 月 前

openssl-3.1.0: Applied and adjusted our OpenSSL changes to 3.0.7. bugref:10418

檔案大小: 19.8 KB
 
1/*
2 * Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright 2004-2014, Akamai Technologies. All Rights Reserved.
4 *
5 * Licensed under the Apache License 2.0 (the "License"). You may not use
6 * this file except in compliance with the License. You can obtain a copy
7 * in the file LICENSE in the source distribution or at
8 * https://www.openssl.org/source/license.html
9 */
10
11/*
12 * This file is in two halves. The first half implements the public API
13 * to be used by external consumers, and to be used by OpenSSL to store
14 * data in a "secure arena." The second half implements the secure arena.
15 * For details on that implementation, see below (look for uppercase
16 * "SECURE HEAP IMPLEMENTATION").
17 */
18#include "internal/e_os.h"
19#include <openssl/crypto.h>
20
21#include <string.h>
22
23#if defined(VBOX)
24# include <iprt/memsafer.h>
25#else
26#ifndef OPENSSL_NO_SECURE_MEMORY
27# if defined(_WIN32)
28# include <windows.h>
29# if defined(WINAPI_FAMILY_PARTITION)
30# if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM)
31/*
32 * While VirtualLock is available under the app partition (e.g. UWP),
33 * the headers do not define the API. Define it ourselves instead.
34 */
35WINBASEAPI
36BOOL
37WINAPI
38VirtualLock(
39 _In_ LPVOID lpAddress,
40 _In_ SIZE_T dwSize
41 );
42# endif
43# endif
44# endif
45# include <stdlib.h>
46# include <assert.h>
47# if defined(OPENSSL_SYS_UNIX)
48# include <unistd.h>
49# endif
50# include <sys/types.h>
51# if defined(OPENSSL_SYS_UNIX)
52# include <sys/mman.h>
53# if defined(__FreeBSD__)
54# define MADV_DONTDUMP MADV_NOCORE
55# endif
56# if !defined(MAP_CONCEAL)
57# define MAP_CONCEAL 0
58# endif
59# endif
60# if defined(OPENSSL_SYS_LINUX)
61# include <sys/syscall.h>
62# if defined(SYS_mlock2)
63# include <linux/mman.h>
64# include <errno.h>
65# endif
66# include <sys/param.h>
67# endif
68# include <sys/stat.h>
69# include <fcntl.h>
70#endif
71#endif /* !VBOX */
72
73#define CLEAR(p, s) OPENSSL_cleanse(p, s)
74#ifndef PAGE_SIZE
75# define PAGE_SIZE 4096
76#endif
77#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
78# define MAP_ANON MAP_ANONYMOUS
79#endif
80
81#ifndef OPENSSL_NO_SECURE_MEMORY
82static size_t secure_mem_used;
83
84static int secure_mem_initialized;
85
86static CRYPTO_RWLOCK *sec_malloc_lock = NULL;
87
88/*
89 * These are the functions that must be implemented by a secure heap (sh).
90 */
91static int sh_init(size_t size, size_t minsize);
92static void *sh_malloc(size_t size);
93static void sh_free(void *ptr);
94static void sh_done(void);
95static size_t sh_actual_size(char *ptr);
96static int sh_allocated(const char *ptr);
97#endif
98
99int CRYPTO_secure_malloc_init(size_t size, size_t minsize)
100{
101#ifndef VBOX
102#ifndef OPENSSL_NO_SECURE_MEMORY
103 int ret = 0;
104
105 if (!secure_mem_initialized) {
106 sec_malloc_lock = CRYPTO_THREAD_lock_new();
107 if (sec_malloc_lock == NULL)
108 return 0;
109 if ((ret = sh_init(size, minsize)) != 0) {
110 secure_mem_initialized = 1;
111 } else {
112 CRYPTO_THREAD_lock_free(sec_malloc_lock);
113 sec_malloc_lock = NULL;
114 }
115 }
116
117 return ret;
118#else
119 return 0;
120#endif /* OPENSSL_NO_SECURE_MEMORY */
121#else
122 return 0;
123#endif /* VBOX */
124}
125
126int CRYPTO_secure_malloc_done(void)
127{
128#ifndef VBOX
129#ifndef OPENSSL_NO_SECURE_MEMORY
130 if (secure_mem_used == 0) {
131 sh_done();
132 secure_mem_initialized = 0;
133 CRYPTO_THREAD_lock_free(sec_malloc_lock);
134 sec_malloc_lock = NULL;
135 return 1;
136 }
137#endif /* OPENSSL_NO_SECURE_MEMORY */
138#endif /* VBOX */
139 return 0;
140}
141
142int CRYPTO_secure_malloc_initialized(void)
143{
144#ifndef VBOX
145#ifndef OPENSSL_NO_SECURE_MEMORY
146 return secure_mem_initialized;
147#else
148 return 0;
149#endif /* OPENSSL_NO_SECURE_MEMORY */
150#else
151 return 0;
152#endif /* VBOX */
153}
154
155void *CRYPTO_secure_malloc(size_t num, const char *file, int line)
156{
157#ifndef VBOX
158#ifndef OPENSSL_NO_SECURE_MEMORY
159 void *ret;
160 size_t actual_size;
161
162 if (!secure_mem_initialized) {
163 return CRYPTO_malloc(num, file, line);
164 }
165 if (!CRYPTO_THREAD_write_lock(sec_malloc_lock))
166 return NULL;
167 ret = sh_malloc(num);
168 actual_size = ret ? sh_actual_size(ret) : 0;
169 secure_mem_used += actual_size;
170 CRYPTO_THREAD_unlock(sec_malloc_lock);
171 return ret;
172#else
173 return CRYPTO_malloc(num, file, line);
174#endif /* OPENSSL_NO_SECURE_MEMORY */
175#else
176 RT_NOREF(line);
177 return RTMemSaferAllocZTag(num, file);
178#endif /* VBOX */
179}
180
181void *CRYPTO_secure_zalloc(size_t num, const char *file, int line)
182{
183#ifndef VBOX
184#ifndef OPENSSL_NO_SECURE_MEMORY
185 if (secure_mem_initialized)
186 /* CRYPTO_secure_malloc() zeroes allocations when it is implemented */
187 return CRYPTO_secure_malloc(num, file, line);
188#endif
189 return CRYPTO_zalloc(num, file, line);
190#else
191 RT_NOREF(line);
192 return RTMemSaferAllocZTag(num, file);
193#endif
194}
195
196void CRYPTO_secure_free(void *ptr, const char *file, int line)
197{
198#ifndef VBOX
199#ifndef OPENSSL_NO_SECURE_MEMORY
200 size_t actual_size;
201
202 if (ptr == NULL)
203 return;
204 if (!CRYPTO_secure_allocated(ptr)) {
205 CRYPTO_free(ptr, file, line);
206 return;
207 }
208 if (!CRYPTO_THREAD_write_lock(sec_malloc_lock))
209 return;
210 actual_size = sh_actual_size(ptr);
211 CLEAR(ptr, actual_size);
212 secure_mem_used -= actual_size;
213 sh_free(ptr);
214 CRYPTO_THREAD_unlock(sec_malloc_lock);
215#else
216 CRYPTO_free(ptr, file, line);
217#endif /* OPENSSL_NO_SECURE_MEMORY */
218#else
219 RT_NOREF(line);
220 RTMemSaferFree(ptr, 0);
221#endif /* VBOX */
222}
223
224void CRYPTO_secure_clear_free(void *ptr, size_t num,
225 const char *file, int line)
226{
227#ifndef VBOX
228#ifndef OPENSSL_NO_SECURE_MEMORY
229 size_t actual_size;
230
231 if (ptr == NULL)
232 return;
233 if (!CRYPTO_secure_allocated(ptr)) {
234 OPENSSL_cleanse(ptr, num);
235 CRYPTO_free(ptr, file, line);
236 return;
237 }
238 if (!CRYPTO_THREAD_write_lock(sec_malloc_lock))
239 return;
240 actual_size = sh_actual_size(ptr);
241 CLEAR(ptr, actual_size);
242 secure_mem_used -= actual_size;
243 sh_free(ptr);
244 CRYPTO_THREAD_unlock(sec_malloc_lock);
245#else
246 if (ptr == NULL)
247 return;
248 OPENSSL_cleanse(ptr, num);
249 CRYPTO_free(ptr, file, line);
250#endif /* OPENSSL_NO_SECURE_MEMORY */
251#else
252 RT_NOREF(line);
253 RTMemSaferFree(ptr, 0);
254#endif /* VBOX */
255}
256
257int CRYPTO_secure_allocated(const void *ptr)
258{
259#ifndef VBOX
260#ifndef OPENSSL_NO_SECURE_MEMORY
261 if (!secure_mem_initialized)
262 return 0;
263 /*
264 * Only read accesses to the arena take place in sh_allocated() and this
265 * is only changed by the sh_init() and sh_done() calls which are not
266 * locked. Hence, it is safe to make this check without a lock too.
267 */
268 return sh_allocated(ptr);
269#else
270 return 0;
271#endif /* OPENSSL_NO_SECURE_MEMORY */
272#else
273 return RTMemSaferGetSize((void *)ptr) > 0;
274#endif /* VBOX */
275}
276
277size_t CRYPTO_secure_used(void)
278{
279#ifndef VBOX
280#ifndef OPENSSL_NO_SECURE_MEMORY
281 return secure_mem_used;
282#else
283 return 0;
284#endif /* OPENSSL_NO_SECURE_MEMORY */
285#else
286 return 0;
287#endif /* VBOX */
288}
289
290size_t CRYPTO_secure_actual_size(void *ptr)
291{
292#ifndef VBOX
293#ifndef OPENSSL_NO_SECURE_MEMORY
294 size_t actual_size;
295
296 if (!CRYPTO_THREAD_write_lock(sec_malloc_lock))
297 return 0;
298 actual_size = sh_actual_size(ptr);
299 CRYPTO_THREAD_unlock(sec_malloc_lock);
300 return actual_size;
301#else
302 return 0;
303#endif
304#else
305 return RTMemSaferGetSize(ptr);
306#endif /* VBOX */
307}
308
309#ifndef VBOX
310/*
311 * SECURE HEAP IMPLEMENTATION
312 */
313#ifndef OPENSSL_NO_SECURE_MEMORY
314
315
316/*
317 * The implementation provided here uses a fixed-sized mmap() heap,
318 * which is locked into memory, not written to core files, and protected
319 * on either side by an unmapped page, which will catch pointer overruns
320 * (or underruns) and an attempt to read data out of the secure heap.
321 * Free'd memory is zero'd or otherwise cleansed.
322 *
323 * This is a pretty standard buddy allocator. We keep areas in a multiple
324 * of "sh.minsize" units. The freelist and bitmaps are kept separately,
325 * so all (and only) data is kept in the mmap'd heap.
326 *
327 * This code assumes eight-bit bytes. The numbers 3 and 7 are all over the
328 * place.
329 */
330
331#define ONE ((size_t)1)
332
333# define TESTBIT(t, b) (t[(b) >> 3] & (ONE << ((b) & 7)))
334# define SETBIT(t, b) (t[(b) >> 3] |= (ONE << ((b) & 7)))
335# define CLEARBIT(t, b) (t[(b) >> 3] &= (0xFF & ~(ONE << ((b) & 7))))
336
337#define WITHIN_ARENA(p) \
338 ((char*)(p) >= sh.arena && (char*)(p) < &sh.arena[sh.arena_size])
339#define WITHIN_FREELIST(p) \
340 ((char*)(p) >= (char*)sh.freelist && (char*)(p) < (char*)&sh.freelist[sh.freelist_size])
341
342
343typedef struct sh_list_st
344{
345 struct sh_list_st *next;
346 struct sh_list_st **p_next;
347} SH_LIST;
348
349typedef struct sh_st
350{
351 char* map_result;
352 size_t map_size;
353 char *arena;
354 size_t arena_size;
355 char **freelist;
356 ossl_ssize_t freelist_size;
357 size_t minsize;
358 unsigned char *bittable;
359 unsigned char *bitmalloc;
360 size_t bittable_size; /* size in bits */
361} SH;
362
363static SH sh;
364
365static size_t sh_getlist(char *ptr)
366{
367 ossl_ssize_t list = sh.freelist_size - 1;
368 size_t bit = (sh.arena_size + ptr - sh.arena) / sh.minsize;
369
370 for (; bit; bit >>= 1, list--) {
371 if (TESTBIT(sh.bittable, bit))
372 break;
373 OPENSSL_assert((bit & 1) == 0);
374 }
375
376 return list;
377}
378
379
380static int sh_testbit(char *ptr, int list, unsigned char *table)
381{
382 size_t bit;
383
384 OPENSSL_assert(list >= 0 && list < sh.freelist_size);
385 OPENSSL_assert(((ptr - sh.arena) & ((sh.arena_size >> list) - 1)) == 0);
386 bit = (ONE << list) + ((ptr - sh.arena) / (sh.arena_size >> list));
387 OPENSSL_assert(bit > 0 && bit < sh.bittable_size);
388 return TESTBIT(table, bit);
389}
390
391static void sh_clearbit(char *ptr, int list, unsigned char *table)
392{
393 size_t bit;
394
395 OPENSSL_assert(list >= 0 && list < sh.freelist_size);
396 OPENSSL_assert(((ptr - sh.arena) & ((sh.arena_size >> list) - 1)) == 0);
397 bit = (ONE << list) + ((ptr - sh.arena) / (sh.arena_size >> list));
398 OPENSSL_assert(bit > 0 && bit < sh.bittable_size);
399 OPENSSL_assert(TESTBIT(table, bit));
400 CLEARBIT(table, bit);
401}
402
403static void sh_setbit(char *ptr, int list, unsigned char *table)
404{
405 size_t bit;
406
407 OPENSSL_assert(list >= 0 && list < sh.freelist_size);
408 OPENSSL_assert(((ptr - sh.arena) & ((sh.arena_size >> list) - 1)) == 0);
409 bit = (ONE << list) + ((ptr - sh.arena) / (sh.arena_size >> list));
410 OPENSSL_assert(bit > 0 && bit < sh.bittable_size);
411 OPENSSL_assert(!TESTBIT(table, bit));
412 SETBIT(table, bit);
413}
414
415static void sh_add_to_list(char **list, char *ptr)
416{
417 SH_LIST *temp;
418
419 OPENSSL_assert(WITHIN_FREELIST(list));
420 OPENSSL_assert(WITHIN_ARENA(ptr));
421
422 temp = (SH_LIST *)ptr;
423 temp->next = *(SH_LIST **)list;
424 OPENSSL_assert(temp->next == NULL || WITHIN_ARENA(temp->next));
425 temp->p_next = (SH_LIST **)list;
426
427 if (temp->next != NULL) {
428 OPENSSL_assert((char **)temp->next->p_next == list);
429 temp->next->p_next = &(temp->next);
430 }
431
432 *list = ptr;
433}
434
435static void sh_remove_from_list(char *ptr)
436{
437 SH_LIST *temp, *temp2;
438
439 temp = (SH_LIST *)ptr;
440 if (temp->next != NULL)
441 temp->next->p_next = temp->p_next;
442 *temp->p_next = temp->next;
443 if (temp->next == NULL)
444 return;
445
446 temp2 = temp->next;
447 OPENSSL_assert(WITHIN_FREELIST(temp2->p_next) || WITHIN_ARENA(temp2->p_next));
448}
449
450
451static int sh_init(size_t size, size_t minsize)
452{
453 int ret;
454 size_t i;
455 size_t pgsize;
456 size_t aligned;
457#if defined(_WIN32)
458 DWORD flOldProtect;
459 SYSTEM_INFO systemInfo;
460#endif
461
462 memset(&sh, 0, sizeof(sh));
463
464 /* make sure size is a powers of 2 */
465 OPENSSL_assert(size > 0);
466 OPENSSL_assert((size & (size - 1)) == 0);
467 if (size == 0 || (size & (size - 1)) != 0)
468 goto err;
469
470 if (minsize <= sizeof(SH_LIST)) {
471 OPENSSL_assert(sizeof(SH_LIST) <= 65536);
472 /*
473 * Compute the minimum possible allocation size.
474 * This must be a power of 2 and at least as large as the SH_LIST
475 * structure.
476 */
477 minsize = sizeof(SH_LIST) - 1;
478 minsize |= minsize >> 1;
479 minsize |= minsize >> 2;
480 if (sizeof(SH_LIST) > 16)
481 minsize |= minsize >> 4;
482 if (sizeof(SH_LIST) > 256)
483 minsize |= minsize >> 8;
484 minsize++;
485 } else {
486 /* make sure minsize is a powers of 2 */
487 OPENSSL_assert((minsize & (minsize - 1)) == 0);
488 if ((minsize & (minsize - 1)) != 0)
489 goto err;
490 }
491
492 sh.arena_size = size;
493 sh.minsize = minsize;
494 sh.bittable_size = (sh.arena_size / sh.minsize) * 2;
495
496 /* Prevent allocations of size 0 later on */
497 if (sh.bittable_size >> 3 == 0)
498 goto err;
499
500 sh.freelist_size = -1;
501 for (i = sh.bittable_size; i; i >>= 1)
502 sh.freelist_size++;
503
504 sh.freelist = OPENSSL_zalloc(sh.freelist_size * sizeof(char *));
505 OPENSSL_assert(sh.freelist != NULL);
506 if (sh.freelist == NULL)
507 goto err;
508
509 sh.bittable = OPENSSL_zalloc(sh.bittable_size >> 3);
510 OPENSSL_assert(sh.bittable != NULL);
511 if (sh.bittable == NULL)
512 goto err;
513
514 sh.bitmalloc = OPENSSL_zalloc(sh.bittable_size >> 3);
515 OPENSSL_assert(sh.bitmalloc != NULL);
516 if (sh.bitmalloc == NULL)
517 goto err;
518
519 /* Allocate space for heap, and two extra pages as guards */
520#if defined(_SC_PAGE_SIZE) || defined (_SC_PAGESIZE)
521 {
522# if defined(_SC_PAGE_SIZE)
523 long tmppgsize = sysconf(_SC_PAGE_SIZE);
524# else
525 long tmppgsize = sysconf(_SC_PAGESIZE);
526# endif
527 if (tmppgsize < 1)
528 pgsize = PAGE_SIZE;
529 else
530 pgsize = (size_t)tmppgsize;
531 }
532#elif defined(_WIN32)
533 GetSystemInfo(&systemInfo);
534 pgsize = (size_t)systemInfo.dwPageSize;
535#else
536 pgsize = PAGE_SIZE;
537#endif
538 sh.map_size = pgsize + sh.arena_size + pgsize;
539
540#if !defined(_WIN32)
541# ifdef MAP_ANON
542 sh.map_result = mmap(NULL, sh.map_size,
543 PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE|MAP_CONCEAL, -1, 0);
544# else
545 {
546 int fd;
547
548 sh.map_result = MAP_FAILED;
549 if ((fd = open("/dev/zero", O_RDWR)) >= 0) {
550 sh.map_result = mmap(NULL, sh.map_size,
551 PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
552 close(fd);
553 }
554 }
555# endif
556 if (sh.map_result == MAP_FAILED)
557 goto err;
558#else
559 sh.map_result = VirtualAlloc(NULL, sh.map_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
560
561 if (sh.map_result == NULL)
562 goto err;
563#endif
564
565 sh.arena = (char *)(sh.map_result + pgsize);
566 sh_setbit(sh.arena, 0, sh.bittable);
567 sh_add_to_list(&sh.freelist[0], sh.arena);
568
569 /* Now try to add guard pages and lock into memory. */
570 ret = 1;
571
572#if !defined(_WIN32)
573 /* Starting guard is already aligned from mmap. */
574 if (mprotect(sh.map_result, pgsize, PROT_NONE) < 0)
575 ret = 2;
576#else
577 if (VirtualProtect(sh.map_result, pgsize, PAGE_NOACCESS, &flOldProtect) == FALSE)
578 ret = 2;
579#endif
580
581 /* Ending guard page - need to round up to page boundary */
582 aligned = (pgsize + sh.arena_size + (pgsize - 1)) & ~(pgsize - 1);
583#if !defined(_WIN32)
584 if (mprotect(sh.map_result + aligned, pgsize, PROT_NONE) < 0)
585 ret = 2;
586#else
587 if (VirtualProtect(sh.map_result + aligned, pgsize, PAGE_NOACCESS, &flOldProtect) == FALSE)
588 ret = 2;
589#endif
590
591#if defined(OPENSSL_SYS_LINUX) && defined(MLOCK_ONFAULT) && defined(SYS_mlock2)
592 if (syscall(SYS_mlock2, sh.arena, sh.arena_size, MLOCK_ONFAULT) < 0) {
593 if (errno == ENOSYS) {
594 if (mlock(sh.arena, sh.arena_size) < 0)
595 ret = 2;
596 } else {
597 ret = 2;
598 }
599 }
600#elif defined(_WIN32)
601 if (VirtualLock(sh.arena, sh.arena_size) == FALSE)
602 ret = 2;
603#else
604 if (mlock(sh.arena, sh.arena_size) < 0)
605 ret = 2;
606#endif
607#ifdef MADV_DONTDUMP
608 if (madvise(sh.arena, sh.arena_size, MADV_DONTDUMP) < 0)
609 ret = 2;
610#endif
611
612 return ret;
613
614 err:
615 sh_done();
616 return 0;
617}
618
619static void sh_done(void)
620{
621 OPENSSL_free(sh.freelist);
622 OPENSSL_free(sh.bittable);
623 OPENSSL_free(sh.bitmalloc);
624#if !defined(_WIN32)
625 if (sh.map_result != MAP_FAILED && sh.map_size)
626 munmap(sh.map_result, sh.map_size);
627#else
628 if (sh.map_result != NULL && sh.map_size)
629 VirtualFree(sh.map_result, 0, MEM_RELEASE);
630#endif
631 memset(&sh, 0, sizeof(sh));
632}
633
634static int sh_allocated(const char *ptr)
635{
636 return WITHIN_ARENA(ptr) ? 1 : 0;
637}
638
639static char *sh_find_my_buddy(char *ptr, int list)
640{
641 size_t bit;
642 char *chunk = NULL;
643
644 bit = (ONE << list) + (ptr - sh.arena) / (sh.arena_size >> list);
645 bit ^= 1;
646
647 if (TESTBIT(sh.bittable, bit) && !TESTBIT(sh.bitmalloc, bit))
648 chunk = sh.arena + ((bit & ((ONE << list) - 1)) * (sh.arena_size >> list));
649
650 return chunk;
651}
652
653static void *sh_malloc(size_t size)
654{
655 ossl_ssize_t list, slist;
656 size_t i;
657 char *chunk;
658
659 if (size > sh.arena_size)
660 return NULL;
661
662 list = sh.freelist_size - 1;
663 for (i = sh.minsize; i < size; i <<= 1)
664 list--;
665 if (list < 0)
666 return NULL;
667
668 /* try to find a larger entry to split */
669 for (slist = list; slist >= 0; slist--)
670 if (sh.freelist[slist] != NULL)
671 break;
672 if (slist < 0)
673 return NULL;
674
675 /* split larger entry */
676 while (slist != list) {
677 char *temp = sh.freelist[slist];
678
679 /* remove from bigger list */
680 OPENSSL_assert(!sh_testbit(temp, slist, sh.bitmalloc));
681 sh_clearbit(temp, slist, sh.bittable);
682 sh_remove_from_list(temp);
683 OPENSSL_assert(temp != sh.freelist[slist]);
684
685 /* done with bigger list */
686 slist++;
687
688 /* add to smaller list */
689 OPENSSL_assert(!sh_testbit(temp, slist, sh.bitmalloc));
690 sh_setbit(temp, slist, sh.bittable);
691 sh_add_to_list(&sh.freelist[slist], temp);
692 OPENSSL_assert(sh.freelist[slist] == temp);
693
694 /* split in 2 */
695 temp += sh.arena_size >> slist;
696 OPENSSL_assert(!sh_testbit(temp, slist, sh.bitmalloc));
697 sh_setbit(temp, slist, sh.bittable);
698 sh_add_to_list(&sh.freelist[slist], temp);
699 OPENSSL_assert(sh.freelist[slist] == temp);
700
701 OPENSSL_assert(temp-(sh.arena_size >> slist) == sh_find_my_buddy(temp, slist));
702 }
703
704 /* peel off memory to hand back */
705 chunk = sh.freelist[list];
706 OPENSSL_assert(sh_testbit(chunk, list, sh.bittable));
707 sh_setbit(chunk, list, sh.bitmalloc);
708 sh_remove_from_list(chunk);
709
710 OPENSSL_assert(WITHIN_ARENA(chunk));
711
712 /* zero the free list header as a precaution against information leakage */
713 memset(chunk, 0, sizeof(SH_LIST));
714
715 return chunk;
716}
717
718static void sh_free(void *ptr)
719{
720 size_t list;
721 void *buddy;
722
723 if (ptr == NULL)
724 return;
725 OPENSSL_assert(WITHIN_ARENA(ptr));
726 if (!WITHIN_ARENA(ptr))
727 return;
728
729 list = sh_getlist(ptr);
730 OPENSSL_assert(sh_testbit(ptr, list, sh.bittable));
731 sh_clearbit(ptr, list, sh.bitmalloc);
732 sh_add_to_list(&sh.freelist[list], ptr);
733
734 /* Try to coalesce two adjacent free areas. */
735 while ((buddy = sh_find_my_buddy(ptr, list)) != NULL) {
736 OPENSSL_assert(ptr == sh_find_my_buddy(buddy, list));
737 OPENSSL_assert(ptr != NULL);
738 OPENSSL_assert(!sh_testbit(ptr, list, sh.bitmalloc));
739 sh_clearbit(ptr, list, sh.bittable);
740 sh_remove_from_list(ptr);
741 OPENSSL_assert(!sh_testbit(ptr, list, sh.bitmalloc));
742 sh_clearbit(buddy, list, sh.bittable);
743 sh_remove_from_list(buddy);
744
745 list--;
746
747 /* Zero the higher addressed block's free list pointers */
748 memset(ptr > buddy ? ptr : buddy, 0, sizeof(SH_LIST));
749 if (ptr > buddy)
750 ptr = buddy;
751
752 OPENSSL_assert(!sh_testbit(ptr, list, sh.bitmalloc));
753 sh_setbit(ptr, list, sh.bittable);
754 sh_add_to_list(&sh.freelist[list], ptr);
755 OPENSSL_assert(sh.freelist[list] == ptr);
756 }
757}
758
759static size_t sh_actual_size(char *ptr)
760{
761 int list;
762
763 OPENSSL_assert(WITHIN_ARENA(ptr));
764 if (!WITHIN_ARENA(ptr))
765 return 0;
766 list = sh_getlist(ptr);
767 OPENSSL_assert(sh_testbit(ptr, list, sh.bittable));
768 return sh.arena_size / (ONE << list);
769}
770#endif /* OPENSSL_NO_SECURE_MEMORY */
771#endif /* VBOX */
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette