You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs: recast "Arbitrary read" as "Exploit primitives"
Reframe post-primitive KASLR bypass around two co-equal targets — the image
slide and the direct-map (page_offset) base — instead of slide-first, and give
data-only its own paths. Five techniques: object-pointer leak (dual-target),
fixed-structure read (IDT gates), in-kernel symbol resolution, corruption
without a leak, and probing candidate bases. Expand references (SCTPhantom,
DirtyPipe, Copy Fail, Beyond Control, PageJack, modprobe_path scan) and
propagate the rename through the ToC, exploitation.md, and the technique-map
diagram.
***Pointer-chasing** — leak any object pointer (a `task_struct`, a namespace),
598
+
then traverse to one whose target is a fixed `.data`/`.bss` symbol (`init_task`,
599
+
`init_cred`, `init_net`, `init_pid_ns`, `init_mm`, `init_ipc_ns`); the
600
+
traversal, not the first read, lands the known symbol.
601
+
602
+
**To the direct-map base**, the object's own storage is the target: any slab
603
+
object's address is a linear-map pointer, so leaking a heap pointer — a list
604
+
neighbour, a self-reference, a back-pointer — bounds `page_offset` regardless of
605
+
which object it belongs to. This is the data-only pivot: the recovered base makes a
606
+
sprayed or target object (`cred`, page-table pages, a `pipe_buffer`) addressable,
607
+
then feeds a data-only read/write primitive such as `pipe_buffer.page` AARW.
608
+
609
+
The `msg_msg` structure is the usual delivery vehicle for either: corrupting its
610
+
`m_ts` length or `next` pointer turns a one-shot overflow into a controlled
611
+
over-read into an adjacent object. A write primitive discloses nothing by itself,
612
+
but the same bug's write is frequently what builds the read.
613
+
614
+
Leaking a kernel pointer from a reachable object (`msg_msg` and related objects):
559
615
560
616
*[Four Bytes of Power: Exploiting CVE-2021-26708 in the Linux kernel | Alexander Popov](https://a13xp0p0v.github.io/2021/02/09/CVE-2021-26708.html)
561
617
*[CVE-2021-22555: Turning \x00\x00 into 10000$ | security-research](https://google.github.io/security-research/pocs/linux/cve-2021-22555/writeup.html)
@@ -564,6 +620,47 @@ Leaking kernel addresses using `msg_msg` struct for arbitrary read (for `KMALLOC
564
620
*[Will's Root: corCTF 2021 Fire of Salvation Writeup: Utilizing msg_msg Objects for Arbitrary Read and Arbitrary Write in the Linux Kernel](https://www.willsroot.io/2021/08/corctf-2021-fire-of-salvation-writeup.html)
565
621
*[[corCTF 2021] Wall Of Perdition: Utilizing msg_msg Objects For Arbitrary Read And Arbitrary Write In The Linux Kernel](https://syst3mfailure.io/wall-of-perdition)
566
622
*[[CVE-2021-42008] Exploiting A 16-Year-Old Vulnerability In The Linux 6pack Driver](https://syst3mfailure.io/sixpack-slab-out-of-bounds)
623
+
*[CVE-2022-0185: Linux kernel slab out-of-bounds write: exploit and writeup](https://www.openwall.com/lists/oss-security/2022/01/25/14) — partial-overwrite of `msg_msg.m_ts` extends the read to leak `init_ipc_ns` via a sprayed `shm_file_data`
624
+
*[\[CVE-2022-1786\] A Journey To The Dawn | kylebot's Blog](https://blog.kylebot.net/2022/10/16/CVE-2022-1786/) — `timerfd_ctx` list pointers and armed-timer `.text` callbacks
625
+
*[HTB UNI CTF 2021: Steam Driver Kernel Pwnable](https://www.hackthebox.com/blog/uni-ctf-writeup-steam-driver) — `msg_msg` user-copy KASLR rebase
626
+
*[Escaping the Google kCTF Container with a Data-Only Exploit](https://h0mbre.github.io/kCTF_Data_Only_Exploit/) (h0mbre) — `init_task`/`cred` traversal, data-only
627
+
*[pipe_buffer exploitation experiments](https://a13xp0p0v.github.io/2026/04/20/pipe-buffer-experiments.html) (Alexander Popov, 2026) — data-only `pipe_buffer.page` AARW; the direct-map pivot a recovered base feeds
628
+
629
+
### Reading a fixed, KASLR-invariant structure
630
+
631
+
A true arbitrary read — one that dereferences an attacker-chosen absolute address
632
+
— can target a structure mapped at a fixed, KASLR-independent address whose
633
+
contents are slid kernel-text pointers, sidestepping the object grooming above.
634
+
The interrupt descriptor table is the canonical target: on x86-64 a read-only IDT
635
+
alias is mapped at the constant address `0xfffffe0000000000` (`CPU_ENTRY_AREA_RO_IDT`,
636
+
equal to `CPU_ENTRY_AREA_BASE` and unmoved by KASLR), while each gate still holds
637
+
the runtime address of its handler.
638
+
639
+
A 16-byte gate splits the 64-bit handler across `offset_low` (bits 0–15),
640
+
`offset_middle` (16–31) and `offset_high` (32–63). Because the image slide is
641
+
2 MiB-aligned, the low 21 bits of every handler are invariant and the top half is
642
+
the canonical `0xffffffff…` window, so the only unknown bits — the slide entropy —
643
+
sit in `offset_middle`; a single 32-bit read across that field reconstructs the
644
+
handler, and subtracting the link-time symbol (gate 0 → `asm_exc_divide_error`)
645
+
yields the slide. This is the memory-disclosure successor to the unprivileged
646
+
`SIDT`/`SGDT` instruction leak (see [Side-channels](#side-channels)), which read
647
+
the IDT/GDT *base*: the fixed read-only alias and UMIP defeat the instruction, but
648
+
neither touches the gate *contents*, so an arbitrary read recovers the slide even
649
+
where `SIDT` is blocked.
650
+
651
+
*[SIMPLE IS BETTER: Kernel Information Leak with Unprivileged Instructions (SIDT, SGDT) on x86](http://hypervsir.blogspot.com/2014/10/kernel-information-leak-with.html)
652
+
*[make cpu-entry-area great again — kqx](https://kqx.io/post/sp0/) — fixed IDT mapping and `cea_offset` randomization
653
+
*[SCTPhantom (CVE-2026-64564)](https://matrix.tencent.com/en/2026/08/06/sctphantom-CVE-2026-64564) — IDT gate 0 read from a repeatable 4-byte kernel read, bypassing UMIP
654
+
655
+
### Resolving symbols from an in-kernel vantage
656
+
657
+
The strongest primitives — arbitrary read/write from kernel context, or kernel
658
+
code execution — make recovery direct rather than inferential: an attacker inside
659
+
the kernel can read the compiled `kallsyms` tables, read a `.text` pointer from a
660
+
CPU register (`rdmsr MSR_LSTAR` returns `entry_SYSCALL_64`), walk page tables from
661
+
`CR3`, or read descriptor-table and segment state from ring 0. The task shifts from
662
+
defeating KASLR to resolving symbol addresses under restrictions such as
663
+
`kptr_restrict`.
567
664
568
665
Leaking kernel addresses using privileged arbitrary read (or write) in kernel space:
569
666
@@ -572,3 +669,48 @@ Leaking kernel addresses using privileged arbitrary read (or write) in kernel sp
*[CVE-2026-31431 "Copy Fail"](https://www.sysdig.com/blog/cve-2026-31431-copy-fail-linux-kernel-flaw-lets-local-users-gain-root-in-seconds) (2026) — `algif_aead`/`AF_ALG` + `splice()` 4-byte page-cache write corrupts a setuid binary for root, no KASLR required (fix reverts commit `72548b093ee3`)
697
+
*[Beyond Control: Exploring Novel File System Objects for Data-Only Attacks on Linux Systems](https://arxiv.org/abs/2401.17618) (2024) — systematic study of data-only file-subsystem targets, many exploitable without a KASLR bypass
698
+
*[Page-UAF / PageJack (Black Hat USA 2024)](https://github.com/Lotuhu/Page-UAF) — page-level UAF PoCs (CVE-2021-22555, CVE-2022-0185, CVE-2022-0995, CVE-2023-5345); almost none require bypassing KASLR
699
+
*[Exploit Methods/Function pointer overwrite - Linux Kernel Security Subsystem](https://kernsec.org/wiki/index.php/Exploit_Methods/Function_pointer_overwrite) — where `.text`/fops/descriptor-table pointers live
700
+
701
+
### Probing candidate bases
702
+
703
+
With no leaked pointer to read directly, the base can still be found by *probing*
704
+
the 2 MiB-aligned candidates: a survivable arbitrary read can scan them for the
705
+
kernel's mapped contents, or — where nothing can be read back — an observable
706
+
non-fatal side effect can distinguish a mapped from an unmapped address. A wrong
707
+
guess that panics is single-shot, so a purely fatal primitive cannot be
708
+
brute-forced this way, unlike the userland [Brute force](#brute-force) case.
709
+
710
+
*[Overwriting the modprobe_path](https://ian.nl/blog/overwrite-modprobe-path) (ian.nl) — recovers the slide by scanning 2 MiB-aligned bases with an arbitrary read, then overwrites `modprobe_path`
711
+
712
+
## See also
713
+
714
+
*[xairy/linux-kernel-exploitation](https://github.com/xairy/linux-kernel-exploitation) — curated Linux kernel exploitation reference collection
715
+
*[Kernel Address Space Layout Randomization (KASLR)](https://breaking-bits.gitbook.io/breaking-bits/exploit-development/linux-kernel-exploit-development/kernel-address-space-layout-randomization-kalsr) — exploit-development walkthrough
716
+
*[Exploiting a Linux Kernel Infoleak to bypass Linux kASLR](https://marcograss.github.io/security/linux/2016/01/24/exploiting-infoleak-linux-kaslr-bypass.html) (Marco Grassi, 2016)
0 commit comments