# [CVE-2022-1786] A Journey To The Dawn

io_uring identity confusion in Linux kernel leads to invalid free, exploited via heap grooming, timerfd ROP, and binfmt overwrite for container escape.

- Payout: $91,337
- Severity: high
- Program: Google (kCTF), Linux Kernel Organization
- Credited: kylebot
- Disclosed: 2022-10-15
- CVE: CVE-2022-1786
- Write-up quality: 10/10
- Original: https://blog.kylebot.net/2022/10/16/CVE-2022-1786/
- Library page: https://bugbountylibrary.com/r/blog%3Ablog-kylebot-net-2022-10-16-cve-2022-1786
- Tags: domain:oss impact:privesc kind:bounty platform:blog sev:high tech:linux technique:chained technique:race-window technique:source-review vuln:memory-corruption vuln:privilege-escalation vuln:race-condition

**Target:** io_uring subsystem
**Root cause:** io_req_init_async assumes current task is the submitter, but when a thread exits and reaps IOPOLL requests, it assigns its own identity to requests from other tasks, causing a type confusion and invalid free of a pointer into io_uring_task.
**Steps:**
1. Enable IORING_SETUP_IOPOLL and open a file with O_DIRECT (e.g., /etc/resolv.conf).
2. Submit an async read request from one thread while another thread calls execve to exit.
3. The exiting thread reaps the request and assigns its own identity, leading to invalid free of &io_uring_task->__identity.
4. Heap groom kmalloc-256 with msg_msgseg objects to control adjacent slots.
5. Trigger the bug and use side-channel on msg_msgseg to detect success.
6. Leak heap and KASLR from timerfd_ctx placed in invalid slot.
7. Hijack timerfd_ctx->tmr.function to ROP, overwrite binfmt, and use telefork to return to userspace with root.
**How found:** Analyzed io_uring code and noticed false assumption in io_req_init_async about current task being submitter. Realized race with thread exit and IOPOLL could cause identity confusion.
**Exploitation:** Heap grooming places msg_msgseg at lower slot and timerfd_ctx at invalid slot. After triggering invalid free, leak addresses, overwrite timerfd function pointer to ROP chain that overwrites binfmt load_binary, then msleep to end interrupt context. Execute invalid binary to trigger ROP in task context, perform privilege escalation, and use fork to return to userspace as root.
**Escalation:** Chained invalid free to heap leak, KASLR bypass, arbitrary write via freelist hijack, then binfmt overwrite for PC control and container escape.
**Insight:** When auditing io_uring, look for assumptions about current task context in async request handling, especially during thread exit and IOPOLL reaping. Race conditions with execve can break identity assumptions.
