// https://syzkaller.appspot.com/bug?id=3ce3ffd8320398fb3336831c3cb1e7b3ba60d64a #define _GNU_SOURCE #include #include #include #include #include #include #include #define NUM_PAGES 1000 #define PAGE_SIZE 4096 void *addr; int stop = 0; void *mprotect_thread(void *arg) { long offset = (long)arg; void *target = addr + offset * PAGE_SIZE; while (!__atomic_load_n(&stop, __ATOMIC_RELAXED)) { mprotect(target, PAGE_SIZE, PROT_READ | PROT_WRITE); mprotect(target, PAGE_SIZE, PROT_READ); } return NULL; } void *fault_thread(void *arg) { long offset = (long)arg; void *target = addr + offset * PAGE_SIZE; while (!__atomic_load_n(&stop, __ATOMIC_RELAXED)) { madvise(target, PAGE_SIZE, MADV_DONTNEED); (void)*(volatile char *)target; } return NULL; } int main() { addr = mmap(NULL, NUM_PAGES * PAGE_SIZE, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (addr == MAP_FAILED) { printf("[-] Failed to mmap: %s\n", strerror(errno)); exit(1); } printf("[+] mmap successful.\n"); for (int i = 0; i < NUM_PAGES; i++) { if (i % 2 == 0) { int res = mprotect(addr + i * PAGE_SIZE, PAGE_SIZE, PROT_READ | PROT_WRITE); if (res < 0) { printf("[-] Failed to mprotect: %s\n", strerror(errno)); exit(1); } } } printf("[+] VMA setup successful.\n"); pthread_t t_writer[4]; long writer_offsets[] = {200, 400, 600, 800}; for (int i = 0; i < 4; i++) { int res = pthread_create(&t_writer[i], NULL, mprotect_thread, (void *)writer_offsets[i]); if (res != 0) { printf("[-] Failed to pthread_create writer: %s\n", strerror(res)); exit(1); } } printf("[+] pthread_create writers successful.\n"); pthread_t t_fault[8]; long fault_offsets[] = {199, 201, 399, 401, 599, 601, 799, 801}; for (int i = 0; i < 8; i++) { int res = pthread_create(&t_fault[i], NULL, fault_thread, (void *)fault_offsets[i]); if (res != 0) { printf("[-] Failed to pthread_create fault: %s\n", strerror(res)); exit(1); } } printf("[+] pthread_create readers successful.\n"); sleep(5); __atomic_store_n(&stop, 1, __ATOMIC_RELAXED); for (int i = 0; i < 4; i++) { int res = pthread_join(t_writer[i], NULL); if (res != 0) { printf("[-] Failed to pthread_join writer: %s\n", strerror(res)); exit(1); } } for (int i = 0; i < 8; i++) { int res = pthread_join(t_fault[i], NULL); if (res != 0) { printf("[-] Failed to pthread_join fault: %s\n", strerror(res)); exit(1); } } printf("[+] pthread_join successful.\n"); return 0; }