Code for the paper GeForge (PDF, project page gddr.fail) — a Rowhammer attack on GDDR6 GPU memory. From an unprivileged GPU kernel, induced bit flips in GPU page tables grant arbitrary read/write to GPU/CPU memory, attack other GPU contexts, and ultimately yield a root shell.
.
├── mapping/ (0) anonymised DRAM bank/row layouts
├── fuzzer/ (1) rowhammer pattern fuzzer
├── page-anchoring/ (2) locate a target page frame at runtime (§4)
└── attack/ (3) end-to-end exploit + bit-flip reproduction harness
Each directory has its own README.md with the details. This file is the
entry point.
- RTX 3060 (12 GB GDDR6)
- RTX A6000 (48 GB GDDR6)
bash setup.sh # interactive: ASLR off, multi-user, clocks, pipManual equivalent:
sudo sysctl -w kernel.randomize_va_space=0
sudo systemctl set-default multi-user.target && sudo reboot
sudo nvidia-smi -lgc 2115,2115
pip install -r requirements.txtgpu-tlb (0x5ec1ab/gpu-tlb) is a
companion tool used by mapping/ and attack/ to dump GPU page tables.
Install it under ~/gpu-tlb (override with GPU_TLB_DIR=…).
tests/gf is a thin dispatcher; each subcommand cds into the right
directory and forwards extra flags through.
tests/gf test # no-GPU smoke (also: 'make test')
tests/gf probe # GPU eviction primitive sanity check
tests/gf sync 3060 # tREFI calibration plot
tests/gf layout 3060 # per-bank VA-row layouts
tests/gf fuzz 3060 [vanilla|forge]
tests/gf anchor 3060 <T> # find anchor for target page #T
tests/gf attack 3060 # build + reproduce a known bit flipA6000 works in place of 3060 for any subcommand. Run tests/gf help for the full menu.
make test # ≡ bash tests/smoke.sh ≡ tests/gf test9 checks across tests/gf, all four fuzzer drivers' module-level
constants, gen_layout_1_bank.py (single + parallel batch), and
align_anchor.py. Fixtures in tests/data/.
| Step | Driver | Output |
|---|---|---|
| 0 — sync | fuzzer/sync/sync-<gpu>.sh |
fuzzer/sync/plots/sync_<gpu>.png (tREFI delay) |
| 1 — layout | fuzzer/fuzzer_run_layout-<gpu>.sh |
fuzzer/layout/VA-BANK_ROW-DIR_<gpu>/ |
| 2 — fuzz | fuzzer/fuzzer_run-<gpu>.sh |
fuzzer/hammer_logs/ |
| 3 — anchor | page-anchoring/ |
inferred chunk base PA |
| 4 — attack | attack/ |
reproduced flips · root shell |
The static per-bank layouts the fuzzer reads live in
mapping/PA-BANK_ROW-DIR_<gpu>/ (already committed).
@inproceedings{geforge,
title = {GeForge: Hammering GDDR Memory to Forge GPU Page Tables for Fun and Profit},
author = {Wan, Junpeng and Guo, Yanan and Zhang, Zhi and Li, Zhuo and Tian, Dave (Jing) and Zhang, Zhenkai},
booktitle = {Proceedings of the 2026 IEEE Symposium on Security and Privacy (SP)},
year = {2026},
month = may,
publisher = {IEEE},
address = {San Francisco, CA, USA},
}