summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libc/stdlib/malloc-standard/free.c5
-rw-r--r--libc/stdlib/malloc-standard/mallinfo.c3
-rw-r--r--libc/stdlib/malloc-standard/malloc.c6
-rw-r--r--libc/stdlib/malloc-standard/malloc.h12
4 files changed, 21 insertions, 5 deletions
diff --git a/libc/stdlib/malloc-standard/free.c b/libc/stdlib/malloc-standard/free.c
index a2d765d41..f3602cf48 100644
--- a/libc/stdlib/malloc-standard/free.c
+++ b/libc/stdlib/malloc-standard/free.c
@@ -214,8 +214,9 @@ void attribute_hidden __malloc_consolidate(mstate av)
*fb = 0;
do {
+ CHECK_PTR(p);
check_inuse_chunk(p);
- nextp = p->fd;
+ nextp = REVEAL_PTR(&p->fd, p->fd);
/* Slightly streamlined version of consolidation code in free() */
size = p->size & ~PREV_INUSE;
@@ -308,7 +309,7 @@ void free(void* mem)
set_fastchunks(av);
fb = &(av->fastbins[fastbin_index(size)]);
- p->fd = *fb;
+ p->fd = PROTECT_PTR(&p->fd, *fb);
*fb = p;
}
diff --git a/libc/stdlib/malloc-standard/mallinfo.c b/libc/stdlib/malloc-standard/mallinfo.c
index dbe4d49b8..992322341 100644
--- a/libc/stdlib/malloc-standard/mallinfo.c
+++ b/libc/stdlib/malloc-standard/mallinfo.c
@@ -49,7 +49,8 @@ struct mallinfo mallinfo(void)
fastavail = 0;
for (i = 0; i < NFASTBINS; ++i) {
- for (p = av->fastbins[i]; p != 0; p = p->fd) {
+ for (p = av->fastbins[i]; p != 0; p = REVEAL_PTR(&p->fd, p->fd)) {
+ CHECK_PTR(p);
++nfastblocks;
fastavail += chunksize(p);
}
diff --git a/libc/stdlib/malloc-standard/malloc.c b/libc/stdlib/malloc-standard/malloc.c
index 1a6d4dc1c..1f898eb29 100644
--- a/libc/stdlib/malloc-standard/malloc.c
+++ b/libc/stdlib/malloc-standard/malloc.c
@@ -260,12 +260,13 @@ void __do_check_malloc_state(void)
assert(p == 0);
while (p != 0) {
+ CHECK_PTR(p);
/* each chunk claims to be inuse */
__do_check_inuse_chunk(p);
total += chunksize(p);
/* chunk belongs in this bin */
assert(fastbin_index(chunksize(p)) == i);
- p = p->fd;
+ p = REVEAL_PTR(&p->fd, p->fd);
}
}
@@ -855,7 +856,8 @@ void* malloc(size_t bytes)
if ((unsigned long)(nb) <= (unsigned long)(av->max_fast)) {
fb = &(av->fastbins[(fastbin_index(nb))]);
if ( (victim = *fb) != 0) {
- *fb = victim->fd;
+ CHECK_PTR(victim);
+ *fb = REVEAL_PTR(&victim->fd, victim->fd);
check_remalloced_chunk(victim, nb);
retval = chunk2mem(victim);
goto DONE;
diff --git a/libc/stdlib/malloc-standard/malloc.h b/libc/stdlib/malloc-standard/malloc.h
index 44120d388..30a696e5a 100644
--- a/libc/stdlib/malloc-standard/malloc.h
+++ b/libc/stdlib/malloc-standard/malloc.h
@@ -839,6 +839,18 @@ typedef struct malloc_chunk* mfastbinptr;
#define get_max_fast(M) \
((M)->max_fast & ~(FASTCHUNKS_BIT | ANYCHUNKS_BIT))
+/*
+ Safe-Linking:
+ Use randomness from ASLR (mmap_base) to protect single-linked lists
+ of fastbins. Together with allocation alignment checks, this mechanism
+ reduces the risk of pointer hijacking, as was done with Safe-Unlinking
+ in the double-linked lists of smallbins.
+*/
+#define PROTECT_PTR(pos, ptr) ((mchunkptr)((((size_t)pos) >> PAGE_SHIFT) ^ ((size_t)ptr)))
+#define REVEAL_PTR(pos, ptr) PROTECT_PTR(pos, ptr)
+#define CHECK_PTR(P) \
+ if (!aligned_OK(P)) \
+ abort();
/*
morecore_properties is a status word holding dynamically discovered