rename quarantine size -> length for clarity
parent
bc2cb5c828
commit
ccc2a86501
10
Android.bp
10
Android.bp
|
@ -15,14 +15,14 @@ common_cflags = [
|
||||||
"-DWRITE_AFTER_FREE_CHECK=true",
|
"-DWRITE_AFTER_FREE_CHECK=true",
|
||||||
"-DSLOT_RANDOMIZE=true",
|
"-DSLOT_RANDOMIZE=true",
|
||||||
"-DSLAB_CANARY=true",
|
"-DSLAB_CANARY=true",
|
||||||
"-DSLAB_QUARANTINE_RANDOM_SIZE=0",
|
"-DSLAB_QUARANTINE_RANDOM_LENGTH=0",
|
||||||
"-DSLAB_QUARANTINE_QUEUE_SIZE=0",
|
"-DSLAB_QUARANTINE_QUEUE_LENGTH=0",
|
||||||
"-DGUARD_SLABS_INTERVAL=1",
|
"-DGUARD_SLABS_INTERVAL=1",
|
||||||
"-DGUARD_SIZE_DIVISOR=2",
|
"-DGUARD_SIZE_DIVISOR=2",
|
||||||
"-DREGION_QUARANTINE_RANDOM_SIZE=128",
|
"-DREGION_QUARANTINE_RANDOM_LENGTH=128",
|
||||||
"-DREGION_QUARANTINE_QUEUE_SIZE=1024",
|
"-DREGION_QUARANTINE_QUEUE_LENGTH=1024",
|
||||||
"-DREGION_QUARANTINE_SKIP_THRESHOLD=33554432", // 32MiB
|
"-DREGION_QUARANTINE_SKIP_THRESHOLD=33554432", // 32MiB
|
||||||
"-DFREE_SLABS_QUARANTINE_RANDOM_SIZE=32",
|
"-DFREE_SLABS_QUARANTINE_RANDOM_LENGTH=32",
|
||||||
"-DCONFIG_CLASS_REGION_SIZE=1073741824", // 1GiB
|
"-DCONFIG_CLASS_REGION_SIZE=1073741824", // 1GiB
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
20
Makefile
20
Makefile
|
@ -6,14 +6,14 @@ CONFIG_ZERO_ON_FREE := true
|
||||||
CONFIG_WRITE_AFTER_FREE_CHECK := true
|
CONFIG_WRITE_AFTER_FREE_CHECK := true
|
||||||
CONFIG_SLOT_RANDOMIZE := true
|
CONFIG_SLOT_RANDOMIZE := true
|
||||||
CONFIG_SLAB_CANARY := true
|
CONFIG_SLAB_CANARY := true
|
||||||
CONFIG_SLAB_QUARANTINE_RANDOM_SIZE := 0
|
CONFIG_SLAB_QUARANTINE_RANDOM_LENGTH := 0
|
||||||
CONFIG_SLAB_QUARANTINE_QUEUE_SIZE := 0
|
CONFIG_SLAB_QUARANTINE_QUEUE_LENGTH := 0
|
||||||
CONFIG_GUARD_SLABS_INTERVAL := 1
|
CONFIG_GUARD_SLABS_INTERVAL := 1
|
||||||
CONFIG_GUARD_SIZE_DIVISOR := 2
|
CONFIG_GUARD_SIZE_DIVISOR := 2
|
||||||
CONFIG_REGION_QUARANTINE_RANDOM_SIZE := 128
|
CONFIG_REGION_QUARANTINE_RANDOM_LENGTH := 128
|
||||||
CONFIG_REGION_QUARANTINE_QUEUE_SIZE := 1024
|
CONFIG_REGION_QUARANTINE_QUEUE_LENGTH := 1024
|
||||||
CONFIG_REGION_QUARANTINE_SKIP_THRESHOLD := 33554432 # 32MiB
|
CONFIG_REGION_QUARANTINE_SKIP_THRESHOLD := 33554432 # 32MiB
|
||||||
CONFIG_FREE_SLABS_QUARANTINE_RANDOM_SIZE := 32
|
CONFIG_FREE_SLABS_QUARANTINE_RANDOM_LENGTH := 32
|
||||||
CONFIG_CLASS_REGION_SIZE := 137438953472 # 128GiB
|
CONFIG_CLASS_REGION_SIZE := 137438953472 # 128GiB
|
||||||
|
|
||||||
define safe_flag
|
define safe_flag
|
||||||
|
@ -71,14 +71,14 @@ CPPFLAGS += \
|
||||||
-DWRITE_AFTER_FREE_CHECK=$(CONFIG_WRITE_AFTER_FREE_CHECK) \
|
-DWRITE_AFTER_FREE_CHECK=$(CONFIG_WRITE_AFTER_FREE_CHECK) \
|
||||||
-DSLOT_RANDOMIZE=$(CONFIG_SLOT_RANDOMIZE) \
|
-DSLOT_RANDOMIZE=$(CONFIG_SLOT_RANDOMIZE) \
|
||||||
-DSLAB_CANARY=$(CONFIG_SLAB_CANARY) \
|
-DSLAB_CANARY=$(CONFIG_SLAB_CANARY) \
|
||||||
-DSLAB_QUARANTINE_RANDOM_SIZE=$(CONFIG_SLAB_QUARANTINE_RANDOM_SIZE) \
|
-DSLAB_QUARANTINE_RANDOM_LENGTH=$(CONFIG_SLAB_QUARANTINE_RANDOM_LENGTH) \
|
||||||
-DSLAB_QUARANTINE_QUEUE_SIZE=$(CONFIG_SLAB_QUARANTINE_QUEUE_SIZE) \
|
-DSLAB_QUARANTINE_QUEUE_LENGTH=$(CONFIG_SLAB_QUARANTINE_QUEUE_LENGTH) \
|
||||||
-DGUARD_SLABS_INTERVAL=$(CONFIG_GUARD_SLABS_INTERVAL) \
|
-DGUARD_SLABS_INTERVAL=$(CONFIG_GUARD_SLABS_INTERVAL) \
|
||||||
-DGUARD_SIZE_DIVISOR=$(CONFIG_GUARD_SIZE_DIVISOR) \
|
-DGUARD_SIZE_DIVISOR=$(CONFIG_GUARD_SIZE_DIVISOR) \
|
||||||
-DREGION_QUARANTINE_RANDOM_SIZE=$(CONFIG_REGION_QUARANTINE_RANDOM_SIZE) \
|
-DREGION_QUARANTINE_RANDOM_LENGTH=$(CONFIG_REGION_QUARANTINE_RANDOM_LENGTH) \
|
||||||
-DREGION_QUARANTINE_QUEUE_SIZE=$(CONFIG_REGION_QUARANTINE_QUEUE_SIZE) \
|
-DREGION_QUARANTINE_QUEUE_LENGTH=$(CONFIG_REGION_QUARANTINE_QUEUE_LENGTH) \
|
||||||
-DREGION_QUARANTINE_SKIP_THRESHOLD=$(CONFIG_REGION_QUARANTINE_SKIP_THRESHOLD) \
|
-DREGION_QUARANTINE_SKIP_THRESHOLD=$(CONFIG_REGION_QUARANTINE_SKIP_THRESHOLD) \
|
||||||
-DFREE_SLABS_QUARANTINE_RANDOM_SIZE=$(CONFIG_FREE_SLABS_QUARANTINE_RANDOM_SIZE) \
|
-DFREE_SLABS_QUARANTINE_RANDOM_LENGTH=$(CONFIG_FREE_SLABS_QUARANTINE_RANDOM_LENGTH) \
|
||||||
-DCONFIG_CLASS_REGION_SIZE=$(CONFIG_CLASS_REGION_SIZE)
|
-DCONFIG_CLASS_REGION_SIZE=$(CONFIG_CLASS_REGION_SIZE)
|
||||||
|
|
||||||
libhardened_malloc.so: $(OBJECTS)
|
libhardened_malloc.so: $(OBJECTS)
|
||||||
|
|
17
README.md
17
README.md
|
@ -140,24 +140,25 @@ The following boolean configuration options are available:
|
||||||
The following integer configuration options are available. Proper sanity checks
|
The following integer configuration options are available. Proper sanity checks
|
||||||
for the chosen values are not written yet, so use them at your own peril:
|
for the chosen values are not written yet, so use them at your own peril:
|
||||||
|
|
||||||
* `CONFIG_SLAB_QUARANTINE_RANDOM_SIZE`: `0` (default) to control the number of
|
* `CONFIG_SLAB_QUARANTINE_RANDOM_LENGTH`: `0` (default) to control the number
|
||||||
slots in the random array used to randomize reuse for small memory
|
of slots in the random array used to randomize reuse for small memory
|
||||||
allocations
|
allocations
|
||||||
* `CONFIG_SLAB_QUARANTINE_QUEUE_SIZE`: `0` (default) to control the number of
|
* `CONFIG_SLAB_QUARANTINE_QUEUE_LENGTH`: `0` (default) to control the number of
|
||||||
slots in the queue used to delay reuse for small memory allocations
|
slots in the queue used to delay reuse for small memory allocations
|
||||||
* `CONFIG_GUARD_SLABS_INTERVAL`: `1` (default) to control the number of slabs
|
* `CONFIG_GUARD_SLABS_INTERVAL`: `1` (default) to control the number of slabs
|
||||||
before a slab is skipped and left as an unused memory protected guard slab
|
before a slab is skipped and left as an unused memory protected guard slab
|
||||||
* `CONFIG_GUARD_SIZE_DIVISOR`: `2` (default) to control the maximum size of the
|
* `CONFIG_GUARD_SIZE_DIVISOR`: `2` (default) to control the maximum size of the
|
||||||
guard regions placed on both sides of large memory allocations, relative to
|
guard regions placed on both sides of large memory allocations, relative to
|
||||||
the usable size of the memory allocation
|
the usable size of the memory allocation
|
||||||
* `CONFIG_REGION_QUARANTINE_RANDOM_SIZE`: `128` (default) to control the number
|
* `CONFIG_REGION_QUARANTINE_RANDOM_LENGTH`: `128` (default) to control the
|
||||||
of slots in the random array used to randomize region reuse for large memory
|
number of slots in the random array used to randomize region reuse for large
|
||||||
|
memory allocations
|
||||||
|
* `CONFIG_REGION_QUARANTINE_QUEUE_LENGTH`: `1024` (default) to control the
|
||||||
|
number of slots in the queue used to delay region reuse for large memory
|
||||||
allocations
|
allocations
|
||||||
* `CONFIG_REGION_QUARANTINE_QUEUE_SIZE`: `1024` (default) to control the number
|
|
||||||
of slots in the queue used to delay region reuse for large memory allocations
|
|
||||||
* `CONFIG_REGION_QUARANTINE_SKIP_THRESHOLD`: `33554432` (default) to control
|
* `CONFIG_REGION_QUARANTINE_SKIP_THRESHOLD`: `33554432` (default) to control
|
||||||
the size threshold where large allocations will not be quarantined
|
the size threshold where large allocations will not be quarantined
|
||||||
* `CONFIG_FREE_SLABS_QUARANTINE_RANDOM_SIZE`: `32` (default) to control the
|
* `CONFIG_FREE_SLABS_QUARANTINE_RANDOM_LENGTH`: `32` (default) to control the
|
||||||
number of slots in the random array used to randomize free slab reuse
|
number of slots in the random array used to randomize free slab reuse
|
||||||
* `CONFIG_CLASS_REGION_SIZE`: `34359738368` (default) to control the size of
|
* `CONFIG_CLASS_REGION_SIZE`: `34359738368` (default) to control the size of
|
||||||
the size class regions
|
the size class regions
|
||||||
|
|
32
h_malloc.c
32
h_malloc.c
|
@ -28,7 +28,7 @@ extern int __register_atfork(void (*)(void), void (*)(void), void (*)(void), voi
|
||||||
#define atfork pthread_atfork
|
#define atfork pthread_atfork
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SLAB_QUARANTINE (SLAB_QUARANTINE_RANDOM_SIZE > 0 || SLAB_QUARANTINE_QUEUE_SIZE > 0)
|
#define SLAB_QUARANTINE (SLAB_QUARANTINE_RANDOM_LENGTH > 0 || SLAB_QUARANTINE_QUEUE_LENGTH > 0)
|
||||||
|
|
||||||
static_assert(sizeof(void *) == 8, "64-bit only");
|
static_assert(sizeof(void *) == 8, "64-bit only");
|
||||||
|
|
||||||
|
@ -177,12 +177,12 @@ struct __attribute__((aligned(CACHELINE_SIZE))) size_class {
|
||||||
struct libdivide_u32_t size_divisor;
|
struct libdivide_u32_t size_divisor;
|
||||||
struct libdivide_u64_t slab_size_divisor;
|
struct libdivide_u64_t slab_size_divisor;
|
||||||
|
|
||||||
#if SLAB_QUARANTINE_RANDOM_SIZE > 0
|
#if SLAB_QUARANTINE_RANDOM_LENGTH > 0
|
||||||
void *quarantine_random[SLAB_QUARANTINE_RANDOM_SIZE];
|
void *quarantine_random[SLAB_QUARANTINE_RANDOM_LENGTH];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SLAB_QUARANTINE_QUEUE_SIZE > 0
|
#if SLAB_QUARANTINE_QUEUE_LENGTH > 0
|
||||||
void *quarantine_queue[SLAB_QUARANTINE_QUEUE_SIZE];
|
void *quarantine_queue[SLAB_QUARANTINE_QUEUE_LENGTH];
|
||||||
size_t quarantine_queue_index;
|
size_t quarantine_queue_index;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -202,7 +202,7 @@ struct __attribute__((aligned(CACHELINE_SIZE))) size_class {
|
||||||
// FIFO singly-linked list
|
// FIFO singly-linked list
|
||||||
struct slab_metadata *free_slabs_head;
|
struct slab_metadata *free_slabs_head;
|
||||||
struct slab_metadata *free_slabs_tail;
|
struct slab_metadata *free_slabs_tail;
|
||||||
struct slab_metadata *free_slabs_quarantine[FREE_SLABS_QUARANTINE_RANDOM_SIZE];
|
struct slab_metadata *free_slabs_quarantine[FREE_SLABS_QUARANTINE_RANDOM_LENGTH];
|
||||||
|
|
||||||
struct random_state rng;
|
struct random_state rng;
|
||||||
size_t metadata_allocated;
|
size_t metadata_allocated;
|
||||||
|
@ -523,8 +523,8 @@ static size_t slab_usable_size(const void *p) {
|
||||||
static void enqueue_free_slab(struct size_class *c, struct slab_metadata *metadata) {
|
static void enqueue_free_slab(struct size_class *c, struct slab_metadata *metadata) {
|
||||||
metadata->next = NULL;
|
metadata->next = NULL;
|
||||||
|
|
||||||
static_assert(FREE_SLABS_QUARANTINE_RANDOM_SIZE < (u16)-1, "free slabs quarantine too large");
|
static_assert(FREE_SLABS_QUARANTINE_RANDOM_LENGTH < (u16)-1, "free slabs quarantine too large");
|
||||||
size_t index = get_random_u16_uniform(&c->rng, FREE_SLABS_QUARANTINE_RANDOM_SIZE);
|
size_t index = get_random_u16_uniform(&c->rng, FREE_SLABS_QUARANTINE_RANDOM_LENGTH);
|
||||||
struct slab_metadata *substitute = c->free_slabs_quarantine[index];
|
struct slab_metadata *substitute = c->free_slabs_quarantine[index];
|
||||||
c->free_slabs_quarantine[index] = metadata;
|
c->free_slabs_quarantine[index] = metadata;
|
||||||
|
|
||||||
|
@ -590,8 +590,8 @@ static inline void deallocate_small(void *p, const size_t *expected_size) {
|
||||||
|
|
||||||
set_quarantine(metadata, slot);
|
set_quarantine(metadata, slot);
|
||||||
|
|
||||||
#if SLAB_QUARANTINE_RANDOM_SIZE > 0
|
#if SLAB_QUARANTINE_RANDOM_LENGTH > 0
|
||||||
size_t random_index = get_random_u16_uniform(&c->rng, SLAB_QUARANTINE_RANDOM_SIZE);
|
size_t random_index = get_random_u16_uniform(&c->rng, SLAB_QUARANTINE_RANDOM_LENGTH);
|
||||||
void *random_substitute = c->quarantine_random[random_index];
|
void *random_substitute = c->quarantine_random[random_index];
|
||||||
c->quarantine_random[random_index] = p;
|
c->quarantine_random[random_index] = p;
|
||||||
|
|
||||||
|
@ -603,10 +603,10 @@ static inline void deallocate_small(void *p, const size_t *expected_size) {
|
||||||
p = random_substitute;
|
p = random_substitute;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SLAB_QUARANTINE_QUEUE_SIZE > 0
|
#if SLAB_QUARANTINE_QUEUE_LENGTH > 0
|
||||||
void *queue_substitute = c->quarantine_queue[c->quarantine_queue_index];
|
void *queue_substitute = c->quarantine_queue[c->quarantine_queue_index];
|
||||||
c->quarantine_queue[c->quarantine_queue_index] = p;
|
c->quarantine_queue[c->quarantine_queue_index] = p;
|
||||||
c->quarantine_queue_index = (c->quarantine_queue_index + 1) % SLAB_QUARANTINE_QUEUE_SIZE;
|
c->quarantine_queue_index = (c->quarantine_queue_index + 1) % SLAB_QUARANTINE_QUEUE_LENGTH;
|
||||||
|
|
||||||
if (queue_substitute == NULL) {
|
if (queue_substitute == NULL) {
|
||||||
mutex_unlock(&c->lock);
|
mutex_unlock(&c->lock);
|
||||||
|
@ -683,8 +683,8 @@ struct region_allocator {
|
||||||
struct region_metadata *regions;
|
struct region_metadata *regions;
|
||||||
size_t total;
|
size_t total;
|
||||||
size_t free;
|
size_t free;
|
||||||
struct quarantine_info quarantine_random[REGION_QUARANTINE_RANDOM_SIZE];
|
struct quarantine_info quarantine_random[REGION_QUARANTINE_RANDOM_LENGTH];
|
||||||
struct quarantine_info quarantine_queue[REGION_QUARANTINE_QUEUE_SIZE];
|
struct quarantine_info quarantine_queue[REGION_QUARANTINE_QUEUE_LENGTH];
|
||||||
size_t quarantine_queue_index;
|
size_t quarantine_queue_index;
|
||||||
struct random_state rng;
|
struct random_state rng;
|
||||||
};
|
};
|
||||||
|
@ -723,7 +723,7 @@ static void regions_quarantine_deallocate_pages(void *p, size_t size, size_t gua
|
||||||
|
|
||||||
mutex_lock(&ra->lock);
|
mutex_lock(&ra->lock);
|
||||||
|
|
||||||
size_t index = get_random_u64_uniform(&ra->rng, REGION_QUARANTINE_RANDOM_SIZE);
|
size_t index = get_random_u64_uniform(&ra->rng, REGION_QUARANTINE_RANDOM_LENGTH);
|
||||||
struct quarantine_info b = ra->quarantine_random[index];
|
struct quarantine_info b = ra->quarantine_random[index];
|
||||||
ra->quarantine_random[index] = a;
|
ra->quarantine_random[index] = a;
|
||||||
if (b.p == NULL) {
|
if (b.p == NULL) {
|
||||||
|
@ -733,7 +733,7 @@ static void regions_quarantine_deallocate_pages(void *p, size_t size, size_t gua
|
||||||
|
|
||||||
a = ra->quarantine_queue[ra->quarantine_queue_index];
|
a = ra->quarantine_queue[ra->quarantine_queue_index];
|
||||||
ra->quarantine_queue[ra->quarantine_queue_index] = b;
|
ra->quarantine_queue[ra->quarantine_queue_index] = b;
|
||||||
ra->quarantine_queue_index = (ra->quarantine_queue_index + 1) % REGION_QUARANTINE_QUEUE_SIZE;
|
ra->quarantine_queue_index = (ra->quarantine_queue_index + 1) % REGION_QUARANTINE_QUEUE_LENGTH;
|
||||||
|
|
||||||
mutex_unlock(&ra->lock);
|
mutex_unlock(&ra->lock);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue