
Enhanced fuzzing for tmux using OSS-Fuzz. Includes custom `cmd-fuzzer` and `argument-fuzzer` harnesses for improved code coverage and a PoC for `CVE-2020-27347`
Software Security @ EPFL, Spring 2025
In this lab, we enhanced the fuzzing efforts for the tmux terminal multiplexer within Google's OSS-Fuzz infrastructure. We first established a baseline by evaluating the line coverage of the existing input-fuzzer harness, both with and without its provided seed corpus, noting comparable initial coverage. Following this, we identified two significant code regions in tmux poorly exercised by the baseline fuzzer. To address these coverage gaps, we developed and evaluated two new targeted fuzzing harnesses, cmd-fuzzer and argument-fuzzer, demonstrating their ability to improve coverage in these previously under-tested areas. As these fuzzing improvements did not uncover new critical vulnerabilities within the project's timeframe, our crash analysis focused on a known historical vulnerability. We developed a proof-of-concept (PoC) for CVE-2020-27347 (a stack-based buffer overflow), analyzed its root cause, discussed the implemented fix, and assessed its security implications.
This project aimed to apply and enhance fuzzing techniques on the tmux open-source terminal multiplexer, utilizing the OSS-Fuzz framework. The project encompassed several key stages:
Baseline Evaluation (Part 1):
input-fuzzer harness for tmux.Coverage Gap Analysis (Part 2):
tmux not adequately exercised by the input-fuzzer.arguments.c) and command parsing/execution logic (cmd-parse.c, cmd-*.c modules) as key areas for improvement.Fuzzer Improvement (Part 3):
argument-fuzzer: Specifically designed to test the command-line argument parsing logic in arguments.c.cmd-fuzzer: Designed to test the command parsing and execution pathways, targeting cmd-parse.c and various modules.The final submission is organized as follows (within the submission/ directory):
submission/
├── README.md # This file
├── part_1/ # Files for Part 1: Baseline Evaluation
│ ├── oss-fuzz.diff # Diff for removing seed corpus for input-fuzzer
│ ├── project.diff # (Likely empty or minor for Part 1)
│ ├── remove_seed_corpus.patch # The actual patch file used
│ ├── report/ # HTML Coverage reports for input-fuzzer
│ │ ├── w_corpus/
│ │ └── wo_corpus/
│ ├── run.w_corpus.sh # Script to run input-fuzzer with corpus
│ └── run.wo_corpus.sh # Script to run input-fuzzer without corpus
├── part_3/ # Files for Part 3: Fuzzer Improvements
│ ├── coverage_noimprove/ # Baseline coverage (e.g., from input-fuzzer without corpus)
│ │ └── ...
│ ├── improve1/ # Improvement 1: argument-fuzzer
│ │ ├── coverage_improve1/ # Coverage report for argument-fuzzer
│ │ ├── oss-fuzz.diff # OSS-Fuzz config changes for argument-fuzzer
│ │ ├── project.diff # Tmux changes for argument-fuzzer (e.g., new .cc, Makefile.am)
│ │ └── run.improve1.sh # Script to run argument-fuzzer
│ └── improve2/ # Improvement 2: cmd-fuzzer
│ ├── coverage_improve2/ # Coverage report for cmd-fuzzer
│ ├── oss-fuzz.diff # OSS-Fuzz config changes for cmd-fuzzer
│ ├── project.diff # Tmux changes for cmd-fuzzer
│ └── run.improve2.sh # Script to run cmd-fuzzer
├── part_4/ # Files for Part 4: Crash Analysis (CVE-2020-27347)
│ ├── environment/ # Docker environment for PoC
│ │ ├── Dockerfile
│ │ ├── run_tmux_cve_test.sh # Core PoC test logic
│ │ ├── test_fixed.sh
│ │ └── test_vulnerable.sh
│ └── run.poc.sh # Script to build Docker image and run PoC tests
└── report.pdf # The comprehensive project report
(Note: The scripts/ directory containing _run_fuzz_core.sh is a helper and would be part of the root if this README is at the true project root alongside submission/)
All fuzzing campaigns and the CVE PoC reproduction are designed to be run within Docker environments orchestrated by shell scripts.
All fuzzing campaigns and the CVE PoC reproduction are designed to be run within Docker environments orchestrated by shell scripts.
Prerequisites:
bash shell and git client.[email protected] if the scripts need to clone oss-fuzz (they attempt to clone if oss-fuzz/ is not found in the project root). Alternatively, you can pre-clone https://github.com/google/oss-fuzz.git into the project root.General Scripting Architecture:
The project uses a centralized core script, scripts/_run_fuzz_core.sh (not included in the submission/ directory but part of the overall project structure this README assumes). Individual runner scripts located in submission/part_1/, submission/part_3/improve1/, submission/part_3/improve2/, and submission/part_4/ are responsible for:
oss-fuzz.diff patches to a clean checkout of the oss-fuzz repository (expected to be at ../../oss-fuzz relative to most runner scripts).PROJECT, HARNESS, LABEL, paths to project-specific patches, and output directories)._run_fuzz_core.sh script, which then handles:
tmux).submission/ directory structure.Running the Scripts:
It's generally recommended to execute the runner scripts from the project's root directory to ensure correct relative path resolution for oss-fuzz/ and output directories.
1. Part 1: Baseline Evaluation (input-fuzzer)
These scripts evaluate the existing input-fuzzer for tmux.
# From the project root directory:
./submission/part_1/run.w_corpus.sh # Run input-fuzzer with default seed corpus
./submission/part_1/run.wo_corpus.sh # Run input-fuzzer without seed corpus
run.w_corpus.sh uses the default tmux build behavior regarding seeds.
run.wo_corpus.sh applies submission/part_1/remove_seed_corpus.patch (via its local oss-fuzz.diff which would call out to this patch or integrate its changes) to the oss-fuzz/projects/tmux/build.sh to ensure no initial seed corpus is used. Coverage reports are exported to submission/part_1/report/w_corpus/ and submission/part_1/report/wo_corpus/ and submission/part_1/report/wo_corpus/ respectively.
2. Part 3: Fuzzer Improvements (input-fuzzer)
Improvement 1 (argument-fuzzer): Targets arguments.c.
# From the project root directory:
./submission/part_3/improve1/run.improve1.sh
Improvement 2 (cmd-fuzzer): Targets cmd-parse.c and command execution.
# From the project root directory:
./submission/part_3/improve2/run.improve2.sh
Each run.improveX.sh script applies its local oss-fuzz.diff and sets PROJECT_PATCH_FILE to its local project.diff (which adds the new fuzzer code to tmux and updates Makefile.am). Coverage reports are exported to the respective submission/part_3/improveX/coverage_improveX/ directories. The submission/part_3/coverage_noimprove/ directory contains baseline coverage from Part 1 for comparison.
# From the project root directory:
./submission/part_4/run.poc.sh
This script builds a dedicated Docker image (from submission/part_4/environment/Dockerfile) and tests tmux 3.1b (vulnerable) against the patched commit a868bac.
(Detailed explanations, figures, and tables can be found in the full report.pdf)
input-fuzzer.arguments.c), command parsing/execution (cmd-parse.c, cmd-*.c), and client/server logic (client.c, server.c), were largely unexercised (e.g., arguments.c at ~5.8% line coverage).argument-fuzzer (targeting arguments.c): Achieved 66.62% line coverage for arguments.c, a substantial increase from the ~5.8% baseline.cmd-fuzzer (targeting command parsing & execution): Increased line coverage for cmd-parse.c to 42.58% (from ~27%) and function coverage to 77.78%.arguments.c coverage also rose to 45.54% through this fuzzer.cmd.c reached 39.14% line coverage.cmd-*.c modules (e.g., cmd-bind-key.c, cmd-set-options.c to 50% function coverage) and key-handling routines (key-string.c to 30% line coverage, key-bindings.c to 6.05% line coverage).6a33a12) using the payload \033[::::::7::1:2:3::5:6:7:m.a868bac (which includes the fix and leads to version 3.1c) was not susceptible to the crash.argument-fuzzer, cmd-fuzzer) necessitated a good understanding of tmux's internal argument and command processing logic to target specific unexercised code paths.cmd-fuzzer to cover a wider array of cmd-*.c modules, especially those dealing with complex state interactions like window, layout, or pane manipulations.cmd-parse.y to generate more syntactically valid and complex command sequences.cmd-*.cCrash Analysis (Part 4):
tmux (CVE-2020-27347) was selected for in-depth analysis.