1#define _GNU_SOURCE 1
2
3#include <assert.h>
4#include <stdio.h>
5#include <stdlib.h>
6#include <pthread.h>
7
8static char* s_mem;
9static volatile int s_freed;
10
11static 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
21int 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