
CVE-2026-46242 'Bad Epoll'의 Aarch64 개념 증명(PoC) 검사기로, 리눅스 커널의 epoll close-vs-close use-after-free 경쟁(race) 조건을 트리거하여 로컬 권한 상승을 검증합니다.
이 저장소는 x86용으로 이미 존재하는 익스플로잇을 기반으로 한 aarch64 커널용 Bad Epoll 검증기입니다.
epollUse-After-Free 경쟁 조건을 통한 Linux 커널 로컬 권한 상승
| 필드 | 상세 |
|---|---|
| CVE | CVE-2026-46242 |
| 별칭 | Bad Epoll |
| 유형 | 경쟁 조건을 통한 Use-After-Free (UAF) |
| CVSS | 7.8 (높음) |
| 영향 | 로컬 권한 상승 → root |
| 영향받는 커널 | 5.10 – 6.11 (LTS & COS) |
| 서브시스템 | fs/eventpoll.c (ep_remove() / close 경로) |
감시 대상 및 감시 파일 디스크립터에 대한 동시 close() 작업 중 Linux 커널의 epoll 서브시스템에 경쟁 조건이 존재합니다. 두 개의 close 경로가 동시에 실행되면:
ep_remove()를 통해 eventpoll 객체를 해제합니다.hlist_del_rcu() 쓰기가 이미 해제된 메모리에 도달합니다.이로 인해 재할당된 eventpoll의 refs 목록을 손상시키는 Use-After-Free가 발생하며, 살아남은 epoll 대기자에 댕글링 epi->ffd.file 포인터가 남게 됩니다. 이것이 전체 익스플로잇 체인의 기초가 됩니다.
┌─────────────────────────────────────────────────────────┐
│ 1. KASLR Leak (prefetch side-channel via libxdk) │
├─────────────────────────────────────────────────────────┤
│ 2. Race Trigger (close-vs-close UAF on eventpoll) │
│ ├─ Adaptive timer: stat/exec phases calibrate ahead │
│ ├─ False-sharing: dup()+close() widens race window │
│ └─ Oracle: EPOLL_CTL_ADD depth-3 → ELOOP? │
├─────────────────────────────────────────────────────────┤
│ 3. Reclaim (freed eventpoll → ep_uaf_target) │
│ └─ Dangling epi->ffd.file in ep_uaf_waiter │
├─────────────────────────────────────────────────────────┤
│ 4. Cross-Cache (filp slab → buddy → pipe_buffer) │
│ ├─ Drain per-CPU partial list │
│ ├─ Free enclosing objects → slab page freed │
│ └─ Reclaim as pipe pages (256 × 4 KiB) │
├─────────────────────────────────────────────────────────┤
│ 5. Constrained AAR (fdinfo ino:/sdev: as read oracle) │
│ ├─ Fake file spray tiles forged struct file in pipe │
│ ├─ 8B read: ino: ← i_ino at controlled offset │
│ ├─ 4B read: sdev: ← sigaltstack(sas_ss_sp) cursor │
│ └─ Walk: init_task → find exploit task → resolve │
│ files → fdt → fd[] → pipe_buffer → struct page │
├─────────────────────────────────────────────────────────┤
│ 6. RIP Control (f_op→poll hijack → JOP → ROP) │
│ ├─ Forge f_op = virt, f_count = virt - 1 │
│ ├─ JOP pivot chain lands rsp on controlled page │
│ └─ libxdk ROP: commit_creds(init_cred) + ns switch │
├─────────────────────────────────────────────────────────┤
│ 7. Ret2Usr execve("/bin/bash") as root │
└─────────────────────────────────────────────────────────┘
# aarch64 (크로스 컴파일 또는 네이티브)
aarch64-linux-gnu-gcc -O2 -Wall -pthread -march=armv8-a \
race_check_aarch64.c -o race_check
./race_check [timeout_seconds] # 기본값: 300초 (5분)
./race_check 120 # 2분 제한 시간
| 코드 | 의미 |
|---|---|
0 | 레이스 성공 — 커널이 취약함 |
1 | 시간 초과 — 레이스가 감지되지 않음 (오탐 가능성 있음, 커널이 패치되었음을 입증하지 않음) |
⚠️ 고지: 이 저장소는 교육 및 승인된 보안 연구 목적으로만 제공됩니다. 소유하지 않았거나 명시적 테스트 허가를 받지 않은 시스템에 이 익스플로잇을 무단 사용하는 것은 불법입니다.