
Ein GPU-orientierter, abdeckungsgesteuerter Fuzzer für Userland-CUDA-Anwendungen.
Dieses Repository enthält die Artefakte für cuFuzz, einen GPU-orientierten Coverage-geführten Fuzzer für CUDA-Anwendungen im Userspace. cuFuzz kombiniert Host- und Geräteseitige Coverage-Erfassung mit Sanitizern, um effektiv Fehler in CUDA-Programmen zu finden.

cufuzz-artifacts/
├── src/ # Core cuFuzz components
│ ├── cufuzz_cov_nvbit/ # NVBit-based device-side coverage collection tool
│ └── cufuzz_sand/ # Sanitizer wrappers for SAND integration
├── targets/ # Example fuzzing targets
│ └── sampleApp/ # Simple CUDA app with intentional bug for testing
├── scripts/ # Evaluation and analysis scripts
├── Tools/ # External dependencies
│ ├── AFLplusplus/ # AFL++ fuzzer (git submodule)
│ └── AFLplusplus.patch # cuFuzz patches for AFL++
├── third-party-licenses/ # Third-party license files
│ ├── LICENSE_from_aflplusplus # AFL++ Apache 2.0 license
│ └── LICENSE_from_nvbit # NVBit NVIDIA EULA
├── images/ # Documentation images
├── build.sh # Automated build script
├── verify_build.sh # Quick verification test
├── Dockerfile # Docker container definition
├── LICENSE # Apache License 2.0
└── CONTRIBUTING.md # Contribution guidelines and DCO
cuFuzz wurde mit der folgenden Hardwarekonfiguration getestet:
| Komponente | Spezifikation |
|---|---|
| GPU | NVIDIA A40 (48GB VRAM, Compute Capability 8.6) |
| CPU | Intel Xeon Platinum 8362 (64 Kerne, 2 Threads/Kern) |
| Arbeitsspeicher | 120GB+ RAM empfohlen |
| Speicher | 50GB+ freier Speicherplatz für Docker-Image und Fuzzing-Ausgaben |
Andere GPUs: cuFuzz sollte auf anderen NVIDIA GPUs mit Compute Capability ≥ 7.0 funktionieren. Passen Sie die Umgebungsvariable GPU_ARCH entsprechend an (siehe GPU-Architektur-Konfiguration).
| Komponente | Version |
|---|---|
| Ubuntu | 22.04 LTS |
| NVIDIA Treiber | 570.144 oder kompatibel |
| CUDA Toolkit | 12.9 |
| Docker | 20.10+ (empfohlen) |
| nvidia-container-toolkit | Erforderlich für --gpus Flag-Unterstützung |
| clang | 14 |
Der schnellste Weg, cuFuzz auszuprobieren, ist die Verwendung eines Docker-Containers. Unser Dockerfile verwendet das offizielle NVIDIA CUDA 12.9 Entwicklungsimage.
tar -xzvf cufuzz-artifacts.tar.gz
cd cufuzz-artifacts
# Clone AFL++ (required dependency)
git clone https://github.com/AFLplusplus/AFLplusplus.git Tools/AFLplusplus
cd Tools/AFLplusplus
git checkout 9cac7ced05eb9f36c1d0b02ad594b3b09cd3938b
cd ../..
Erstellen Sie das Docker-Image mit Angabe Ihrer GPU-Architektur:
sudo docker build --build-arg GPU_ARCH=<your_arch> -t cufuzz .
GPU-Architektur-Referenz:
| GPU-Familie | Architektur | Beispiele |
|---|---|---|
| Ampere (Rechenzentrum) | sm_80 | A100 |
| Ampere (Consumer/Pro) | sm_86 | A40, RTX 3090, RTX 3060 |
| Hopper | sm_90 | H100 |
| Ada Lovelace | sm_89 | RTX 4090, L40 |
| Turing | sm_75 | RTX 2080, T4 |
Eine vollständige Liste finden Sie unter: https://developer.nvidia.com/cuda-gpus
Beispiel für A40/RTX 3090:
sudo docker build --build-arg GPU_ARCH=sm_86 -t cufuzz .
Hinweis: Dieser Schritt kann je nach Maschine und Netzwerkverbindung mehrere Minuten dauern.
sudo docker run --rm --gpus all -it -v /:/my_workspace cufuzz bash
Sobald der Docker-Container läuft, überprüfen Sie den Build:
root@container:~/cufuzz# ./verify_build.sh
Installieren Sie die erforderlichen Abhängigkeiten unter Ubuntu 22.04:
apt-get update && apt-get install -y build-essential python3-dev automake cmake git flex \
bison libglib2.0-dev libpixman-1-dev python3-setuptools cargo libgtk-3-dev lld llvm llvm-dev \
clang ninja-build cpio libcapstone-dev wget curl python3-pip vim less libxxhash-dev bc zlib1g-dev
Setzen Sie die Umgebungsvariable GPU_ARCH für Ihre GPU (siehe Architektur-Tabelle oben):
export GPU_ARCH=sm_86 # An Ihre GPU anpassen
cd Tools/AFLplusplus
patch -N -p1 < ../AFLplusplus.patch
export CXX=/usr/bin/clang++-14
export CC=/usr/bin/clang-14
make -j8 &> build.log
Laden Sie NVBit Version 1.7.5 herunter:
mkdir -p Tools/NVBit
wget https://github.com/NVlabs/NVBit/releases/download/v1.7.5/nvbit-Linux-x86_64-1.7.5.tar.bz2
tar -xvf nvbit-Linux-x86_64-1.7.5.tar.bz2
mv nvbit_release_x86_64/* Tools/NVBit/
rm -rf nvbit_release_x86_64 nvbit-Linux-x86_64-1.7.5.tar.bz2
Bauen Sie unser NVBit-Coverage-Tool:
cd src/cufuzz_cov_nvbit/
export GPU_ARCH=sm_86 # An Ihre GPU anpassen
ARCH=$GPU_ARCH make
cd src/cufuzz_sand
AFL_SAN_NO_INST=1 ../../Tools/AFLplusplus/afl-clang-fast -O2 wrapper_san.c -o wrapper_memcheck.out
AFL_SAN_NO_INST=1 ../../Tools/AFLplusplus/afl-clang-fast -DSAN_MODE_INIT -O2 wrapper_san.c -o wrapper_initcheck.out
AFL_SAN_NO_INST=1 ../../Tools/AFLplusplus/afl-clang-fast -DSAN_MODE_RACE -O2 wrapper_san.c -o wrapper_racecheck.out
AFL_SAN_NO_INST=1 ../../Tools/AFLplusplus/afl-clang-fast -DSAN_MODE_ASAN -O2 wrapper_san.c -o wrapper_asan.out
Nachdem Sie cuFuzz gebaut haben, starten Sie das Fuzzing mit folgendem Befehl:
CUFUZZ_MAP_SIZE=65536 AFL_SKIP_CPUFREQ=1 AFL_PRELOAD=/PFAD/ZU/cufuzz_cov.so \
./Tools/AFLplusplus/afl-fuzz -x sample.dict -i input_samples/ -o output_dir/ \
-t 1000000 ./cuda_app.out @@
| Variable | Beschreibung | Beispiel |
|---|---|---|
AFL_SKIP_CPUFREQ | CPU-Skalierungsrichtlinien-Prüfung überspringen | AFL_SKIP_CPUFREQ=1 |
AFL_PRELOAD | Pfad zum NVBit-Coverage-Tool | AFL_PRELOAD=/pfad/zu/cufuzz_cov.so |
| Variable | Beschreibung | Beispiel |
|---|---|---|
CUFUZZ_MAP_SIZE | Größe der Coverage-Karte in Bytes | CUFUZZ_MAP_SIZE=65536 |
COV_PERSISTENT | Unterstützung für AFL persistenten Modus aktivieren (0=nein, 1=ja) | COV_PERSISTENT=1 |
GPU_ARCH | Ziel-GPU-Architektur für Builds | GPU_ARCH=sm_86 |
| Variable | Beschreibung | Beispiel |
|---|---|---|
ORIGINAL_APP | Pfad zur unveränderten (nicht instrumentierten) Anwendung | ORIGINAL_APP=./cuda_app |
SANITIZER_PATH | Pfad zur compute-sanitizer-Binärdatei | SANITIZER_PATH=/usr/local/cuda/bin/compute-sanitizer |
SANITIZER_ARG | Argumente für den Memcheck-Sanitizer | SANITIZER_ARG="--tool=memcheck --error-exitcode 99" |
SANITIZER_ARG_RACE | Argumente für den Racecheck-Sanitizer | SANITIZER_ARG_RACE="--tool=racecheck --error-exitcode 99" |
SANITIZER_ARG_INIT | Argumente für den Initcheck-Sanitizer | SANITIZER_ARG_INIT="--tool=initcheck --error-exitcode 99" |
Die Variable AFL_SAN_ABSTRACTION steuert, welche Eingaben an Sanitizer übergeben werden:
| Wert | Beschreibung | Empfindlichkeit | Leistung |
|---|---|---|---|
all_trace | Alle Eingaben an Sanitizer übergeben | Höchste | Langsamste |
simplify_trace | Eingaben mit eindeutigen Ausführungspfaden übergeben | Hoch | Ausgewogen |
unique_trace | Eingaben mit eindeutigen Coverage-Signaturen übergeben | Mittel | Schneller |
coverage_increase | Nur Eingaben, die Coverage-Erhöhung verursachen, übergeben | Niedrigste | Schnellste |
Empfohlen: AFL_SAN_ABSTRACTION=simplify_trace (Standard)
In diesem Modus verwendet cuFuzz geräteseitige Coverage und führt den Compute-Sanitizer auf einer Teilmenge der Eingaben aus (Eingaben mit eindeutigen Abläufen). Dieser Modus nutzt die SAND-Funktion von AFL++, um die Coverage-Erfassung von der Sanitisierung zu entkoppeln.
cd src/cufuzz_sand
# Sanitizer-Wrapper bauen
AFL_SAN_NO_INST=1 ../../Tools/AFLplusplus/afl-clang-fast -O2 wrapper_san.c -o wrapper_memcheck.out
AFL_SAN_NO_INST=1 ../../Tools/AFLplusplus/afl-clang-fast -DSAN_MODE_INIT -O2 wrapper_san.c -o wrapper_initcheck.out
AFL_SAN_NO_INST=1 ../../Tools/AFLplusplus/afl-clang-fast -DSAN_MODE_RACE -O2 wrapper_san.c -o wrapper_racecheck.out
AFL_SAN_NO_INST=1 ../../Tools/AFLplusplus/afl-clang-fast -DSAN_MODE_ASAN -O2 wrapper_san.c -o wrapper_asan.out
cd ../../targets/sampleApp/
export PATH=/usr/local/cuda/bin/:$PATH
export GPU_ARCH=sm_86 # An Ihre GPU anpassen
# Vanilla-Version bauen (für Sanitizer)
nvcc sampleApp.cu -I/usr/local/cuda/include/ -O2 --ptxas-options "-v" \
--gpu-architecture=$GPU_ARCH -o sampleApp-vanilla.out
# Instrumentierte Version bauen (für Fuzzing)
nvcc sampleApp.cu -I/usr/local/cuda/include/ -O2 --ptxas-options "-v" \
--gpu-architecture=$GPU_ARCH --compiler-bindir ../../Tools/AFLplusplus/afl-clang-fast++ \
-o sampleApp.out
# cuFuzz ausführen
ORIGINAL_APP=./sampleApp-vanilla.out \
SANITIZER_PATH=/usr/local/cuda/bin/compute-sanitizer \
SANITIZER_ARG="--tool=memcheck --report-api-errors=no --error-exitcode 99" \
SANITIZER_ARG_RACE="--tool=racecheck --report-api-errors=no --error-exitcode 99" \
SANITIZER_ARG_INIT="--tool=initcheck --report-api-errors=no --error-exitcode 99" \
CUFUZZ_MAP_SIZE=65536 \
AFL_SKIP_CPUFREQ=1 \
AFL_PRELOAD=../../src/cufuzz_cov_nvbit/cufuzz_cov.so \
../../Tools/AFLplusplus/afl-fuzz -x sample.dict -i in/ -o out/ \
-w ../../src/cufuzz_sand/wrapper_memcheck.out \
-w ../../src/cufuzz_sand/wrapper_racecheck.out \
-w ../../src/cufuzz_sand/wrapper_initcheck.out \
-t 1000000 ./sampleApp.out @@

Ausführung ohne Sanitizer (nicht empfohlen): Entfernen Sie die -w Argumente und die SANITIZER_* Variablen.
Ausführung ohne geräteseitige Coverage (optional): Entfernen Sie AFL_PRELOAD=...cufuzz_cov.so.
In diesem Modus nutzt cuFuzz den AFL++ persistenten Modus, bei dem mehrere Eingaben innerhalb eines einzelnen Prozesses getestet werden. Dies verbessert den Durchsatz erheblich, indem der CUDA-Initialisierungsaufwand amortisiert wird.
Der persistente Modus erfordert Änderungen am Quellcode der Fuzzing-Harness. Siehe AFL++ persistent mode documentation für Details.
cd targets/sampleApp/
export PATH=/usr/local/cuda/bin/:$PATH
export GPU_ARCH=sm_86 # An Ihre GPU anpassen
# Persistent-Mode-Binärdatei bauen
nvcc sampleApp_persistent.cu -I/usr/local/cuda/include/ -O2 --ptxas-options "-v" \
--gpu-architecture=$GPU_ARCH --compiler-bindir ../../Tools/AFLplusplus/afl-clang-fast++ \
-o sampleApp_persistent.out
# cuFuzz im persistenten Modus ausführen
COV_PERSISTENT=1 \
CUFUZZ_MAP_SIZE=65536 \
AFL_SKIP_CPUFREQ=1 \
AFL_PRELOAD=../../src/cufuzz_cov_nvbit/cufuzz_cov.so \
./../../Tools/AFLplusplus/afl-fuzz -x sample.dict -i in/ -o out/ \
-t 1000000 ./sampleApp_persistent.out @@

Der persistente Modus unterstützt auch Sanitizer-Optionen mit: src/cufuzz_sand/wrapper_persistent_san.c
nvidia-smi funktioniert.GPU_ARCH auf die Compute Capability Ihrer GPU.Wir begrüßen Beiträge! Bitte lesen Sie CONTRIBUTING.md für Richtlinien zur Mitarbeit, einschließlich:
Wenn Sie cuFuzz in Ihrer Forschung verwenden, zitieren Sie bitte unser OOPSLA 2026 Paper:
@article{cufuzz2026,
title={Hunting CUDA Bugs at Scale with cuFuzz},
author={Mohamed Tarek Ibn Ziad and Christos Kozyrakis},
journal={Proceedings of the ACM on Programming Languages},
volume={10},
number={OOPSLA1},
article={123},
month={4},
year={2026},
doi={10.1145/3798231}
}
Dieses Projekt ist lizenziert unter der Apache License 2.0 – siehe LICENSE für Details.
Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Dieses Projekt verwendet die folgenden Drittanbieter-Komponenten:
| Komponente | Lizenz | Lizenzdatei |
|---|---|---|
| AFL++ | Apache License 2.0 | third-party-licenses/LICENSE_from_aflplusplus |
| NVBit | NVIDIA EULA | third-party-licenses/LICENSE_from_nvbit |