pmfuzz-fuzz - Generating high-value testcases for triggering crash-consistency PM programs.
pmfuzz-fuzz [-h] [–force-resp FORCE_RESP] [–cores-stage1 CORES_STAGE1] [–cores-stage2 CORES_STAGE2] [–overwrite] [–disable-stage2] [–dry-run] [–progress-interval PROGRESS_INTERVAL] [–progress-file PROGRESS_FILE] [–checks-only] [–verbose] [–version] indir outdir config
PMFuzz: A Persistent Memory Fuzzer, version 1.0 by ShiftLab
- path to directory containing initial test corpus for stage 1. See INPUT-DIRECTORY.
- path to directory for generated test cases for stage 1, works as input for stage 2. See OUTPUT-DIRECTORY.
- Points to the config file to use, should conform to: configs/default.yaml. See CONFIGURATION-FILE.
- –force-resp FORCE_RESP
- Forces response to questions
- –cores-stage1 CORES_STAGE1, -c1 CORES_STAGE1
- Maximum cores stage 1 fuzzer can use, default: 1. Can be specified in config.
- –cores-stage2 CORES_STAGE2, -c2 CORES_STAGE2
- Maximum cores stage 2 fuzzer can use, default: 1. Can be specified in config.
- –overwrite, -o
- Overwrite the output directory
- –disable-stage2, -1
- Disables stage 2. Can be specified in config.
- Enables dry run, no actual commands are executed (Deprecated)
- –progress-interval PROGRESS_INTERVAL
- Interval in seconds for recording progress, default: 60 seconds. Can be specified in config.
- –progress-file PROGRESS_FILE
- Output file for writing progress to a file. Can be specified in config.
- Performs startup checks and exits
- –verbose, -v
- Enables verbose logging to stdout
- show program’s version number and exit
To run PMFuzz without any additional output:
pmfuzz-fuzz \ ./input_directory ./output_directory ./configs/default.yml
To record fuzzing progress, use:
pmfuzz-fuzz \ --progress-file=/tmp/fuzz_progress ./input_directory ./output_directory ./configs/default.yml
To get verbose output of the PMFuzz´s current step, use:
pmfuzz-fuzz \ --verbose \ ./input_directory ./output_directory ./configs/default.yml
PMFuzz needs a non-empty directory with seed inputs for fuzzing. These inputs should be command inputs that PMFuzz can execute using the target program. PMFuzz directly uses these inputs using AFL, see afl-fuzz(1).
On each run, pmfuzz will write to the following files
- <output_dirname>/: Contains all the testcases, pool images, crash sites and other information needed to run PMFuzz.
- <output_dirname>.progress: Tracks the progress of the fuzzing.
- <output_dirname>.progress.events: Tracks events like stage transitions in PMFuzz.
Output Directory Structure
The output directory has the following structure
output directory name +-- @info +-- @dedup | +-- id=001.pm_pool | +-- id=001.testcase | +-- id=001.min.testcase | +-- ... +-- stage=1,iter=0 | +-- afl-results | | +-- master_fuzzer | | +-- queue | | +-- slave_fuzzer01 | | +-- ... | +-- testcases | | +-- id=001.testcase | | +-- ... | +-- pm_images | | +-- id=001.pm_pool | | +-- ... | +-- @dedup_sync | +-- id=001.pm_pool | +-- id=001.testcase | +-- id=001.timer | +-- ... +-- stage=2,iter=1 +-- afl-results | +-- id=0001/master_fuzzer/queue | +-- id=0002/master_fuzzer/queue | +-- ... +-- testcases | +-- id=0001,id=001.testcase | +-- ... | +-- id=0002,id=002.testcase | +-- ... +-- pm_images | +-- id=0001,id=001.pm_pool | +-- ... | +-- id=0002,id=001.pm_pool | +-- ... +-- @dedup_sync +-- id=001.pm_pool +-- id=001.testcase +-- id=001.timer +-- ...
The output directory is co-located with progress file with the same
name as the output directory but has an file-extension of type
.progress’. The columns represent the following values, in-order they
Current time, Total testcases, Total PM testcases, Total paths, Total PM paths, Executions/s, internal-execution-parameter
Each testcase/pm_image/crash_site name is a sequence of one or more
id-tags. Each id-tag is of the format
id=<value> and a sequence of
id-tags are connected using the characters
,. If an id-tag is
after ´.´ this means that the id-tag corresponds to a failure image,
while if an id-tag starts with ‘
,’, then that id-tag is for a PMFuzz
If a testcase has multiple IDs, they move down the hierarchy from left to right. An example fuzzing round and corresponding file name are:
PMFuzz marks all the testcases in the input directory with a unique sequential id starting from 1:
Next round of fuzzing uses the second testcase
id=000002.testcaseto generate 5 new testcases, these testcases will now be named:
Next, PMFuzzes uses the testcase
id=00002,id=00003.testcaseto randomly generate the following crash sites:
(note the use of both kinds separator)
Example testcase/pm_pool/crash_site names:
PMFuzz uses a YAML based file to configure different parameters.
configs/examples directory contains several examples for writing and organizing configurations that PMFuzz can use. If you want to write your own configuration file, include config/default.yml in your new config file and change the values you need.
If you are writing your own configuration, please note the following:
Including Other Configs
PMFuzz supports including one or more configuration files to allow easier customization.
Syntax for including config files is:
include: - base-config-1.yaml - base-config-2.yaml . . - base-config-n.yaml
In case of duplicate keys, values are prioritized (and overwritten) in the order they appear. However, the file including them have highest priority.
Nested includes are not supported.
The following variables are automatically substituted in the config file values:
Points to the PMFuzz root directory (root of this repository)
Points to the
Points to the
Points to the
Here is a simple example that runs PMDK´s RBTree workload in baseline
mode. This configuration overwrites the number of CPU cores used by
the first stage to 4. Note, lines starting with
# are comments.
# Brief: # Runs the Baseline for rbtree include: - configs/base.yml - configs/workload/mapcli.rbtree.yml - configs/run_configs/baseline.yml pmfuzz: stage: "1": cores: 4
This section defines several environment variables that may change PMFuzz´s behavior.
Values set and unset describe the behavior when the environment variable is not set to any value and when the variable is set to any non-empty string (including 0) respectively.
Enables fake mmap by copying the contents (using memcpy) of the pool image to the volatile memory. Mounting the pool to the volatile memory improves fuzzing performance.
Mounts the pool using PMDK´s default mounting functions. Before invoking the target, PMFuzz would create a copy of the pool image and call the target on that image. Depending on the output of the fuzzing,PMFuzz would either save that image for future use, or discard it.
Address of the mount point of the pool. See libpmem(7).
PMDK decides the mount address of the pool.
Disables default PMDK´s behaviour that generates non-identical images for same input. 0
PMFuzz generated images would have random variations that may negatively affect the fuzzing performance and reproducibility.
In case the the PMFUZZ_MODE env variable is set to “IMG_GEN”, a failure point is injected and the PM Image is dumped if the PM pool has changed since the last failure injection. First failure injection always results in an image dump.
Images dump naming pattern:
<pool file name>.<failure id> If a failure
list file is additionally specified using the env variable, the falure
ids that generate dumps are written to that file, one per line.
For more information on FI_MODE see libpmfuzz.c.
Path to a file that libpmfuzz would write the failure IDs to.
Enables debug output from libpmfuzz.
Disables debug output from libpmfuzz.
Enables deep paths in PMFuzz
Forces PMFuzz to generate all crash sites. Use with caution.
Disable testcase size check in AFL++.
Enables AFL++´s default behaviour to check testcase size.
Makes workload delete image on start if the pool exists.
FileNotFoundError for instance´s pid file
Raised when AFL cannot bind to a free core or no core is free.
Random tar command failed
Check if device has any free space left.
shmget (2): No space left on device
Run the following command in your shell to remove all shared memory segments:
$ ipcrm -a
Warning: This removes all user owned shared memory segments, don´t run with superuser privilege or on a machine with other critical applications running.
To modify pmfuzz please look into docs/programming_manual or docs/programming_manual.pdf.
Please report bugs at: ⟨https://github.com/Systems-ShiftLab/pmfuzz/issues⟩
libpmfuzz(7), afl-fuzz(1), afl-cmin(1), afl-tmin(1), afl-gotcpu(1)
PMFuzz was written by ShiftLab, University of Virginia. ⟨https://www.cs.virginia.edu/~smk9u/shiftLab.html⟩
Complete documentation for PMFuzz can be accessed online at ⟨https://github.com/Systems-ShiftLab/pmfuzz/wiki⟩