Last active
February 11, 2016 23:45
-
-
Save thestinger/cd714b870939417d2168 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This double-free is detected with 100% reliability in CopperheadOS via the | |
// malloc quarantine. The malloc quarantine uses a ring buffer to provide a | |
// guaranteed baseline delay and a hash table for detecting double frees. A | |
// double free can also be detected after allocations are flushed from the | |
// quarantine, but only if the slot is still free. | |
// | |
// /data/data/test/test(688) in free(): error: double free 0x8e503300 | |
// Aborted | |
#include <stdlib.h> | |
static const size_t max_allocation_size = 128; | |
// prevent the compiler from optimizing out calls to malloc | |
__attribute__((optimize(0))) | |
int main(void) { | |
void *p[32]; // to be freed | |
void *q[sizeof(p) / sizeof(p[0])]; // to be kept | |
// make some allocations | |
for (size_t i = 0; i < sizeof(p) / sizeof(p[0]); i++) { | |
size_t size = arc4random_uniform(max_allocation_size + 1); | |
p[i] = malloc(size); | |
q[i] = malloc(size); | |
if (!p[i] || !q[i]) { | |
return 1; | |
} | |
} | |
// release the allocations | |
for (size_t i = 0; i < sizeof(p) / sizeof(p[0]); i++) { | |
free(p[i]); | |
} | |
// defeat double-free detection without the quarantine | |
for (size_t i = 0; i < 1024; i++) { | |
malloc(arc4random_uniform(max_allocation_size + 1)); | |
} | |
// double-free a random allocation | |
free(p[arc4random_uniform(sizeof(p) / sizeof(p[0]))]); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This write-after-free is detected with 100% reliability in CopperheadOS via | |
// the malloc quarantine and junk filling. The malloc quarantine uses a ring | |
// buffer to provide a guaranteed baseline delay and the junk filled on free is | |
// validated when allocations are flushed from the quarantine and at exit. | |
// | |
// /data/data/test/test(2172) in validate_delayed_chunks(): error: use after free 0xa60e1200 | |
// Aborted | |
#include <stdlib.h> | |
static const size_t max_allocation_size = 128; | |
// prevent the compiler from optimizing out calls to malloc | |
__attribute__((optimize(0))) | |
int main(void) { | |
char *p[32]; // to be freed | |
char *q[sizeof(p) / sizeof(p[0])]; // to be kept | |
// make some allocations | |
for (size_t i = 0; i < sizeof(p) / sizeof(p[0]); i++) { | |
size_t size = arc4random_uniform(max_allocation_size) + 1; | |
p[i] = malloc(size); | |
q[i] = malloc(size); | |
if (!p[i] || !q[i]) { | |
return 1; | |
} | |
} | |
// release the allocations | |
for (size_t i = 0; i < sizeof(p) / sizeof(p[0]); i++) { | |
free(p[i]); | |
} | |
// write-after-free into a random allocation | |
p[arc4random_uniform(sizeof(p) / sizeof(p[0]))][0] = 'a'; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment