Skip to content

Commit 3a418cc

Browse files
committed
Rework memory allocation to support alignment
This change adds an "allocated" attribute to s2n_blob structures which tracks how much memory we have allocated for the blob. This allows us to implement our own realloc with a simple greedy alloator; always allocate a page aligned unit o memory that is a multiple of the system page size. This change also makes it possible to disable mlock. Future changes will do this for some problematic test cases that trigger mlock exhaustion. Another future change will adjust our connection allocation to use one page per s2n_connection and then multiple pages for the I/O stuffers.
1 parent 8b07d74 commit 3a418cc

6 files changed

Lines changed: 53 additions & 15 deletions

File tree

error/s2n_errno.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ struct s2n_error_translation EN[] = {
3636
{ S2N_ERR_DECRYPT, "error decrypting data" },
3737
{ S2N_ERR_MEMSET, "error calling memset" },
3838
{ S2N_ERR_MEMCPY, "error calling memcpy" },
39-
{ S2N_ERR_REALLOC, "error calling realloc" },
39+
{ S2N_ERR_MADVISE, "error calling madvise" },
40+
{ S2N_ERR_ALLOC, "error allocating memory" },
4041
{ S2N_ERR_MLOCK, "error calling mlock" },
4142
{ S2N_ERR_FSTAT, "error calling fstat" },
4243
{ S2N_ERR_OPEN, "error calling open" },

error/s2n_errno.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ typedef enum {
2727
S2N_ERR_DECRYPT,
2828
S2N_ERR_MEMSET,
2929
S2N_ERR_MEMCPY,
30-
S2N_ERR_REALLOC,
30+
S2N_ERR_MADVISE,
31+
S2N_ERR_ALLOC,
3132
S2N_ERR_MLOCK,
3233
S2N_ERR_FSTAT,
3334
S2N_ERR_OPEN,

utils/s2n_blob.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
struct s2n_blob {
2121
uint8_t *data;
2222
uint32_t size;
23+
uint32_t allocated;
2324
};
2425

2526
extern int s2n_blob_init(struct s2n_blob *b, uint8_t *data, uint32_t size);

utils/s2n_mem.c

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
*/
1515

1616
#include <stdint.h>
17+
#include <unistd.h>
1718
#include <stdlib.h>
1819
#include <sys/mman.h>
1920

@@ -23,48 +24,78 @@
2324
#include "utils/s2n_mem.h"
2425
#include "utils/s2n_safety.h"
2526

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+
2640
int s2n_alloc(struct s2n_blob *b, uint32_t size)
2741
{
2842
b->data = NULL;
29-
43+
b->size = 0;
44+
b->allocated = 0;
3045
GUARD(s2n_realloc(b, size));
3146
return 0;
3247
}
3348

3449
int s2n_realloc(struct s2n_blob *b, uint32_t size)
3550
{
3651
if (size == 0) {
37-
GUARD(s2n_free(b));
52+
return s2n_free(b);
53+
}
54+
55+
if (size < b->allocated) {
56+
b->size = size;
3857
return 0;
3958
}
4059

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);
4465
}
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);
4969
}
70+
71+
b->data = data;
72+
b->size = size;
73+
b->allocated = allocate;
74+
5075
#ifdef MADV_DONTDUMP
5176
if (madvise(b->data, size, MADV_DONTDUMP) < 0) {
5277
GUARD(s2n_free(b));
5378
S2N_ERROR(S2N_ERR_MADVISE);
5479
}
5580
#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+
}
5789

5890
return 0;
5991
}
6092

6193
int s2n_free(struct s2n_blob *b)
6294
{
63-
if (b->data) {
64-
free(b->data);
65-
}
95+
free(b->data);
6696
b->data = NULL;
6797
b->size = 0;
98+
b->allocated = 0;
6899

69100
return 0;
70101
}

utils/s2n_mem.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include <stdint.h>
2121

22+
int s2n_mem_init(void);
2223
int s2n_alloc(struct s2n_blob *b, uint32_t size);
2324
int s2n_realloc(struct s2n_blob *b, uint32_t size);
2425
int s2n_free(struct s2n_blob *b);

utils/s2n_random.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
#include "utils/s2n_safety.h"
3535
#include "utils/s2n_random.h"
36+
#include "utils/s2n_mem.h"
3637

3738
#define ENTROPY_SOURCE "/dev/urandom"
3839

@@ -186,6 +187,8 @@ RAND_METHOD s2n_openssl_rand_method = {
186187

187188
int s2n_init(void)
188189
{
190+
GUARD(s2n_mem_init());
191+
189192
OPEN:
190193
entropy_fd = open(ENTROPY_SOURCE, O_RDONLY);
191194
if (entropy_fd == -1) {

0 commit comments

Comments
 (0)