|
14 | 14 | */ |
15 | 15 |
|
16 | 16 | #include <stdint.h> |
| 17 | +#include <unistd.h> |
17 | 18 | #include <stdlib.h> |
18 | 19 | #include <sys/mman.h> |
19 | 20 |
|
|
23 | 24 | #include "utils/s2n_mem.h" |
24 | 25 | #include "utils/s2n_safety.h" |
25 | 26 |
|
| 27 | +static long page_size = 4096; |
| 28 | +static int use_mlock = 1; |
| 29 | + |
| 30 | +int s2n_mem_init(void) |
| 31 | +{ |
| 32 | + GUARD(page_size = sysconf(_SC_PAGESIZE)); |
| 33 | + if (getenv("S2N_DONT_MLOCK")) { |
| 34 | + use_mlock = 0; |
| 35 | + } |
| 36 | + |
| 37 | + return 0; |
| 38 | +} |
| 39 | + |
26 | 40 | int s2n_alloc(struct s2n_blob *b, uint32_t size) |
27 | 41 | { |
28 | 42 | b->data = NULL; |
29 | | - |
| 43 | + b->size = 0; |
| 44 | + b->allocated = 0; |
30 | 45 | GUARD(s2n_realloc(b, size)); |
31 | 46 | return 0; |
32 | 47 | } |
33 | 48 |
|
34 | 49 | int s2n_realloc(struct s2n_blob *b, uint32_t size) |
35 | 50 | { |
36 | 51 | if (size == 0) { |
37 | | - GUARD(s2n_free(b)); |
| 52 | + return s2n_free(b); |
| 53 | + } |
| 54 | + |
| 55 | + if (size < b->allocated) { |
| 56 | + b->size = size; |
38 | 57 | return 0; |
39 | 58 | } |
40 | 59 |
|
41 | | - uint8_t *data = realloc(b->data, size); |
42 | | - if (data == NULL) { |
43 | | - S2N_ERROR(S2N_ERR_REALLOC); |
| 60 | + uint32_t allocate = page_size * ((size + (page_size - 1)) / page_size); |
| 61 | + |
| 62 | + void *data; |
| 63 | + if (posix_memalign(&data, page_size, allocate)) { |
| 64 | + S2N_ERROR(S2N_ERR_ALLOC); |
44 | 65 | } |
45 | | - b->data = data; |
46 | | - if (mlock(b->data, size) < 0) { |
47 | | - GUARD(s2n_free(b)); |
48 | | - S2N_ERROR(S2N_ERR_MLOCK); |
| 66 | + |
| 67 | + if (b->size) { |
| 68 | + memcpy_check(data, b->data, b->size); |
49 | 69 | } |
| 70 | + |
| 71 | + b->data = data; |
| 72 | + b->size = size; |
| 73 | + b->allocated = allocate; |
| 74 | + |
50 | 75 | #ifdef MADV_DONTDUMP |
51 | 76 | if (madvise(b->data, size, MADV_DONTDUMP) < 0) { |
52 | 77 | GUARD(s2n_free(b)); |
53 | 78 | S2N_ERROR(S2N_ERR_MADVISE); |
54 | 79 | } |
55 | 80 | #endif |
56 | | - b->size = size; |
| 81 | + if (use_mlock == 0) { |
| 82 | + return 0; |
| 83 | + } |
| 84 | + |
| 85 | + if (mlock(b->data, size) < 0) { |
| 86 | + GUARD(s2n_free(b)); |
| 87 | + S2N_ERROR(S2N_ERR_MLOCK); |
| 88 | + } |
57 | 89 |
|
58 | 90 | return 0; |
59 | 91 | } |
60 | 92 |
|
61 | 93 | int s2n_free(struct s2n_blob *b) |
62 | 94 | { |
63 | | - if (b->data) { |
64 | | - free(b->data); |
65 | | - } |
| 95 | + free(b->data); |
66 | 96 | b->data = NULL; |
67 | 97 | b->size = 0; |
| 98 | + b->allocated = 0; |
68 | 99 |
|
69 | 100 | return 0; |
70 | 101 | } |
0 commit comments