1 #define _GNU_SOURCE 1 2 3 #include <assert.h> 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <pthread.h> 7 8 static char* s_mem; 9 static volatile int s_freed; 10 11 static void* thread_func(void* arg) 12 { 13 // Busy-wait until pthread_create() has finished. 14 while (s_freed == 0) 15 pthread_yield(); 16 free(s_mem); 17 __sync_add_and_fetch(&s_freed, 1); 18 return NULL; 19 } 20 21 int main(int argc, char** argv) 22 { 23 pthread_t tid; 24 int quiet; 25 char result; 26 27 quiet = argc > 1; 28 29 s_mem = malloc(10); 30 if (!quiet) 31 fprintf(stderr, "Pointer to allocated memory: %p\n", s_mem); 32 assert(s_mem); 33 pthread_create(&tid, NULL, thread_func, NULL); 34 __sync_add_and_fetch(&s_freed, 1); 35 // Busy-wait until the memory has been freed. 36 while (s_freed == 1) 37 pthread_yield(); 38 // Read-after-free. 39 result = s_mem[0]; 40 if (!quiet) 41 fprintf(stderr, "Read-after-free result: %d\n", result); 42 pthread_join(tid, NULL); 43 fprintf(stderr, "Done.\n"); 44 return 0; 45 } 46