While the CHERI instruction-set architecture extensions for capabilities enable strong spatial memory safety, CHERI lacks built-in temporal safety, particularly for heap allocations. Prior attempts to augment CHERI with temporal safety fall short in terms of scalability, memory overhead, and incomplete security guarantees due to periodical sweeps of the system’s memory to individually revoke stale capabilities. We address these limitations by introducing colored capabilities that add a controlled form of indirection to CHERI’s capability model. This enables provenance tracking of capabilities to their respective allocations via a hardware-managed provenance-validity table, allowing bulk retraction of dangling pointers without needing to quarantine freed memory. Colored capabilities significantly reduce the frequency of capability revocation sweeps while improving security. We realize colored capabilities in PICASSO, an extension of the CHERI-RISC-V architecture on a speculative out-of-order FPGA softcore (CHERI-Toooba). We also integrate colored-capability support into the CheriBSD OS and CHERI-enabled Clang/LLVM toolchain. Our evaluation shows effective mitigation of use-after-free and double-free bugs across all heap- based temporal memory-safety vulnerabilities in NIST Juliet test cases, real-world CVEs, only a small performance overhead on SPEC CPU benchmarks (≈ 5% g.m.), less latency, and more consistent performance in long-running SQLite, PostgreSQL, and gRPC workloads compared to prior work.
More Information
- PICASSO: Scaling CHERI Use-After-Free Protection to Millions of Allocations using Colored Capabilities https://arxiv.org/abs/2602.09131
@misc{Gulmez26,
author = {Gülmez, Merve and Sturm, Ruben and ElAtali, Hossam and Englund, Håkan and
Woodruff, Jonathan and Asokan, N. and Nyman, Thomas},
title = {PICASSO: Scaling CHERI Use-After-Free Protection to
Millions of Allocations using Colored Capabilities},
year = {2026},
doi = {10.48550/ARXIV.2602.09131},
howpublished = {{\tt arXiv:2602.09131 [cs.CR]}},
url = {https://arxiv.org/abs/2602.0913}
}Our artifact can be evaluated at three levels:
| Evaluation Level | Hardware Required | What It Reproduces |
|---|---|---|
| Bluespec Simulator | None (Docker) | MiBench results (Table 1) |
| QEMU Emulation | None | Security evaluation |
| FPGA | Xilinx VCU118 | Performance results |
We provide pre-built bitstreams and binaries under the prebuilt directory.
If you prefer not to build everything manually, you can skip ahead to the relevant evaluation section.
All benchmarks are cross-compiled for CheriBSD using the cheribuild system.
Set the artifact directory (this repository) so paths resolve correctly:
export ARTIFACT_DIR=~/cheri/Colored_UsenixThe security evaluation can be run on either QEMU or FPGA.
Install and run the Juliet test suite:
$ARTIFACT_DIR/utils_script/juliet_install.shCopy test binaries to the FPGA (see FPGA.md for scp instructions).
Inside the FPGA, run the tests:
cd /tmp/juliet-test-suite/bin
sh juliet-run.sh 415
sh juliet-run.sh 416Expected results:
- Double Free (CWE-415): The program gracefully exits with exit code -1 (255).
- Use-After-Free (CWE-416): You should see an In-address Space exception signal 34, resulting in exit code 162.
We validate PICASSO against 11 real-world UAF/Double-Free CVEs from published benchmarks.
See validation/README.md for full details.
cd $ARTIFACT_DIR/validation
./build_all.sh
./transfer.sh root@127.0.0.1 -p 10003Then run the tests from the host:
cd $ARTIFACT_DIR/validation
./run_all_remote.sh root@127.0.0.1 -p 10003The validated CVEs include BZip2 (CVE-2016-3189), libiberty (CVE-2016-4487), nasm (CVE-2017-10686, CVE-2019-8343), libzip (CVE-2019-17582), NGINX njs (CVE-2020-24346), LibreDWG (CVE-2022-35164), Lua (CVE-2019-6706), mjs (issues 73, 78), and yasm (issue 91).
Note: Due to licensing restrictions, we do not provide the SPEC CPU2006 source code. Evaluators must have their own valid SPEC CPU2006 license to reproduce these results.
To build SPEC CPU2006 for CheriBSD:
cd $CHERIBUILD
./cheribuild.py spec2006-riscv64-purecap --spec2006/iso-path /path/to/cpu2006-1.2.isoReplace /path/to/cpu2006-1.2.iso with the path to your SPEC CPU2006 ISO image.
The output for the spec folder.. $HOME_DIR/cheri/build/spec2006-riscv64-purecap-build
After building, prepare the benchmark folder:
# Optional: Remove unnecessary files to reduce folder size
$ARTIFACT_DIR/utils_script/spec/spec_folder_reduce_folder.sh
# Instrument all scripts with time and minimal_stats_counts
$ARTIFACT_DIR/utils_script/spec/automate.pyAfter copying the SPEC folder to the FPGA, run all benchmarks at once:
sh run_all_spec_fpga.sh /bench/SPEC/CINT2006Or run a single benchmark individually:
sh ./464.h264ref/464.h264ref.test.fpga.shThe benchmarks run are: 401.bzip2, 445.gobmk, 456.hmmer, 458.sjeng, 462.libquantum, 464.h264ref, 471.omnetpp, and 483.xalancbmk.
The results for each benchmark will be output to:
<benchmark>/<benchmark>_OUTPUT/
After collecting results for all configurations (baseline, colored_paper, cornucupia),
place the _OUTPUT directories under utils_script/spec/:
utils_script/spec/baseline/<benchmark>_OUTPUT/
utils_script/spec/colored_paper/<benchmark>_OUTPUT/
utils_script/spec/cornucupia/<benchmark>_OUTPUT/
Then run the analysis script to generate overhead tables and figures:
python3 $ARTIFACT_DIR/utils_script/spec/analyze_spec_overhead.pyThis produces:
- Per-benchmark cycle, memory, tagcache, and DRAM traffic overhead tables
- Geometric mean summaries across all benchmarks
- Overhead figures saved as PDF and PNG alongside the script
Build PostgreSQL:
Clone the repo manually under $HOME/cheri/:
git clone https://github.com/CTSRD-CHERI/postgres.git
cd postgres
git apply patches/postgress.diffThen build with cheribuild:
cd $CHERIBUILD
./cheribuild.py postgres-riscv64-purecap -dCopy PostgreSQL to the FPGA (see FPGA.md for scp instructions).
On the FPGA, run the benchmark:
sh ./postgres-bench-stats.sh # This will take a while to create the full databaseOn the host, run the benchmark:
sh $ARTIFACT_DIR/utils_script/postgress/pgbench-client.shcd $CHERIBUILD
./cheribuild.py sqlite-riscv64-purecap -dOn the FPGA, run the benchmark:
sh ./speedtest1Cross-compile all dependencies and gRPC:
cd $CHERIBUILD
./cheribuild.py grpc-native -d
./cheribuild.py grpc-riscv64-purecap -dIf that does not work, manually build each dependency:
cd $CHERIBUILD
./cheribuild.py abseil-riscv64-purecap
./cheribuild.py c-ares-riscv64-purecap
./cheribuild.py googlebenchmark-riscv64-purecap
./cheribuild.py googletest-riscv64-purecap
./cheribuild.py protobuf-riscv64-purecap
./cheribuild.py re2-riscv64-purecap
./cheribuild.py grpc-riscv64-purecapLaunch QEMU with port forwarding for the gRPC worker ports:
cd $CHERIBUILD
./cheribuild.py run-riscv64-purecap --run-riscv64-purecap/extra-tcp-forwarding "10000=10000 10001=10001"By default, the gRPC binaries are installed inside QEMU at:
/usr/local/riscv64-purecap/bin
To run the gRPC benchmark on QEMU, run the following script on your host machine:
$ARTIFACT_DIR/utils_script/grpc/grpc-client-bytes-qemu.shTo run the gRPC benchmark on FPGA, run the following script on your host machine:
$ARTIFACT_DIR/utils_script/grpc/grpc-client-bytes.sh