diff options
author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2020-04-17 15:10:39 -0700 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2020-04-17 15:10:39 -0700 |
commit | f00e31f8a7e180acd52b2fb86649509462622b9d (patch) | |
tree | 68693c92e6af1b807bb851fe4bb5f6e17e9f818c | |
parent | 41ff5cc4f9f360fab0a3fd696ca6aa266eb02cba (diff) | |
download | secret-memory-preloader-f00e31f8a7e180acd52b2fb86649509462622b9d.tar.gz |
refactor in preparation for allocating multiple segments
-rw-r--r-- | preload.c | 80 |
1 files changed, 52 insertions, 28 deletions
@@ -58,11 +58,11 @@ struct segptr { }; struct malloc_state { - struct segptr seg; + struct segptr *seg; struct malloc_chunk free; }; -static struct malloc_state *m; +static struct malloc_state m; static int in_use(struct malloc_chunk *c) { @@ -86,7 +86,7 @@ static struct segptr *chunk_to_segment(struct malloc_chunk *c) { struct segptr *sp; - for (sp = &m->seg; sp != NULL; sp = sp->next) + for (sp = m.seg; sp != NULL; sp = sp->next) if (sp->base <= (char *)c && (char *)c < sp->base + SEG_SIZE) return sp; @@ -113,6 +113,8 @@ static struct malloc_chunk *next_chunk(struct malloc_chunk *c) struct segptr *seg = chunk_to_segment(c); void *n = (char*)c + chunk_size(c); + ASSERT(seg != NULL); + ASSERT((char *)n > seg->base && (char *)n <= seg->base + SEG_SIZE); if (n == seg->base + SEG_SIZE) @@ -130,7 +132,7 @@ static struct malloc_chunk *prev_chunk(struct malloc_chunk *c) static void link_free_chunk(struct malloc_chunk *c) { - struct malloc_chunk *f = &m->free; + struct malloc_chunk *f = &m.free; struct malloc_chunk *b = f->bk; c->fd = f; @@ -152,35 +154,35 @@ static void unlink_free_chunk(struct malloc_chunk *c) static void show_segment(void) { struct malloc_chunk *c; + struct segptr *seg; + int i; if (!debug) return; - printf("SHOW SEGMENT\n"); - for (c = (struct malloc_chunk *)m->seg.base; c != NULL; c = next_chunk(c)) { - printf("%p:%d:%d:%04x:%04x", c, in_use(c), prev_in_use(c), - c->prev_foot, chunk_size(c)); - if (!in_use(c)) - printf(":%p:%p", c->fd, c->bk); - printf("\n"); + for (i = 0, seg = m.seg; seg != NULL; i++, seg = seg->next) { + printf("SHOW SEGMENT %i\n", i); + for (c = (struct malloc_chunk *)seg->base; c != NULL; c = next_chunk(c)) { + printf("%p:%d:%d:%04x:%04x", c, in_use(c), prev_in_use(c), + c->prev_foot, chunk_size(c)); + if (!in_use(c)) + printf(":%p:%p", c->fd, c->bk); + printf("\n"); + } } - printf("SHOW SEGMENT END\n"); } -void __attribute__ ((constructor)) preload_setup(void) +static int use_secret = 1; + +static void alloc_segment(void) { int fd; int ret; void *p; + struct segptr *seg, *sp, **psp; + const size_t ssize = pad_request(sizeof(*seg)); struct malloc_chunk *c; - const size_t msize = pad_request(sizeof(*m)); - int use_secret = 1; - - if (getenv("MALLOC_DEBUG") != NULL) - debug = 1; - if (getenv("NO_SECRET_MEM") != NULL) - use_secret = 0; if (use_secret) fd = memfd_create("secure", MFD_CLOEXEC|MFD_SECRET); @@ -198,28 +200,50 @@ void __attribute__ ((constructor)) preload_setup(void) p = mmap(NULL, SEG_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); check(p == MAP_FAILED, "mmap"); + close(fd); DEBUG("initial malloc at 0x%p-0x%p\n", p, p+SEG_SIZE); c = p; - m = chunk2mem(c); - memset(m, 0, sizeof(*m)); - c->head = msize | CINUSE_BIT | PINUSE_BIT; - m->seg.base = p; + seg = chunk2mem(c); + memset(seg, 0, sizeof(*seg)); + seg->base = p; + c->head = ssize | CINUSE_BIT | PINUSE_BIT; + c->prev_foot = 0; + + if (m.seg == NULL) { + m.seg = seg; + } else { + for (sp = m.seg; sp->next == NULL; sp = sp->next) + ; + sp->next = seg; + } c = next_chunk(c); + printf("NEXT CHUNK %p\n", c); c->head = (size_t)(((char *)p + SEG_SIZE) - (char *)c) | PINUSE_BIT; - c->prev_foot = msize; + c->prev_foot = ssize; DEBUG("next chunk at 0x%p, head=%x, prev=%x\n", c, chunk_size(c), c->prev_foot); - m->free.fd = &m->free; - m->free.bk = &m->free; link_free_chunk(c); } +void __attribute__ ((constructor)) preload_setup(void) +{ + if (getenv("MALLOC_DEBUG") != NULL) + debug = 1; + if (getenv("NO_SECRET_MEM") != NULL) + use_secret = 0; + + m.free.fd = &m.free; + m.free.bk = &m.free; + m.seg = NULL; + alloc_segment(); +} + static struct malloc_chunk *find_free(size_t size) { struct malloc_chunk *c, *found = NULL; - for (c = m->free.fd; c != &m->free; c = c->fd) { + for (c = m.free.fd; c != &m.free; c = c->fd) { if (chunk_size(c) < size) continue; if (found && chunk_size(found) < chunk_size(c)) |