This artifact accompanies the USENIX Security 2027 submission Measurement-Driven Non-Idempotency: Detecting Latent State-Leak Faults in Linux Isolation Tools. It provides:
- The measurement-driven non-idempotency framework (definitions + protocol)
- Formal model of the mount-propagation defect class
- Automated fault-injection campaign (four scenarios + a five-class state-leak generalization)
- A tree-sitter static analyzer for the mount-propagation defect class
- An ecosystem audit of 30 real isolation-related projects
- All measured experimental results from the paper
The central invariant: a correct isolation tool leaves host kernel state unchanged across repeated invocations. Any host-state counter that grows monotonically is a deterministic state-leak signal.
- OS: Ubuntu 22.04+ or similar Linux distribution
- Kernel: 5.15+ (tested on 7.0.0-27-generic)
- Privileges: Root access required (mount namespace operations)
- Dependencies: gcc, make, python3, tree-sitter (see
setup.sh)
# 1. Setup environment (installs deps, compiles test_fi, sets up tree-sitter)
sudo bash setup.sh
# 2. Run all experiments (takes ~5 minutes)
sudo bash run_experiments.sh
# 3. Generate the results report
bash analyze_results.sh
# 4. View results
cat results/REPORT.mdartifact/
├── README.md # This file
├── setup.sh # Environment setup
├── run_experiments.sh # Run all experiments
├── analyze_results.sh # Analyze and generate report
├── src/
│ ├── test_fi.c # Fault injection test binary
│ └── analyzer.py # Static analysis tool (tree-sitter v3)
├── formal_model/
│ └── mount_propagation.tex # Formal model (LaTeX)
├── results/ # Generated after running experiments
│ ├── scenario_a.csv
│ ├── scenario_b.csv
│ ├── scenario_c.csv
│ ├── scenario_d.csv
│ ├── state_leak_leak.csv
│ ├── state_leak_fixed.csv
│ ├── audit_results.csv
│ └── REPORT.md
└── expected/ # Reference results for verification
├── scenario_a.csv
├── scenario_b.csv
├── scenario_c.csv
├── scenario_d.csv
├── state_leak_leak.csv
├── state_leak_fixed.csv
└── audit_results.csv
Tests the core defect: recursive bind mount without MS_PRIVATE.
- Buggy: 1.0 leaks/invocation
- Fixed: 0.0 leaks/invocation
Tests how leak rate scales with pre-existing mount depth (0/5/10/15/20).
- Expected: constant 1.0 leak/invocation (fresh namespaces)
Tests defect manifestation across propagation types.
- Buggy (shared): 1.0, slave: 0.0, fixed (private): 0.0
Tests leak scaling with 1/2/4/8 concurrent processes.
- Expected: linear (each process leaks independently)
A harness (stateleak) deliberately leaks one unit of each of five
non-mount state classes per operation, plus a fixed variant that cleans up.
Classes: open fds, inotify watches, keyring keys, cgroup directories, zombie
children. Counts are read from /proc and keyctl(1).
- Leaky: monotonic growth (e.g., 1 -> 12 by op 12)
- Fixed: flat at baseline
The tree-sitter analyzer detects the mount-propagation defect class in C/C++ source:
python3 src/analyzer.py /path/to/project --project name --jsonIt performs AST-based flag evaluation, intra-procedural ordering, and
inter-procedural fixed-point guard propagation, then emits three-tier
verdicts: vulnerable (unguarded recursive bind), candidate (guard
established in a different function, leak timing unproved), or clean.
| Project | RUB | Prot. | high | med | dyn | Verdict |
|---|---|---|---|---|---|---|
| minijail | 1 | 0 | 1 | 0 | 6 | vulnerable |
| lxc | 2 | 1 | 1 | 0 | 14 | vulnerable |
| bubblewrap | 1 | 0 | 0 | 1 | 4 | candidate |
| crun | 3 | 0 | 0 | 3 | 6 | candidate |
| lxcfs | 1 | 0 | 0 | 1 | 3 | candidate |
| firejail | 18 | 0 | 0 | 18 | 5 | candidate |
| criu | 2 | 1 | 1 | 0 | 24 | candidate |
| nsjail | 0 | 0 | 0 | 0 | 4 | clean |
| runc | 0 | 0 | 0 | 0 | 0 | clean |
| slirp4netns | 0 | 0 | 0 | 0 | 0 | clean |
| util-linux | 0 | 0 | 0 | 0 | 4 | clean |
| busybox | 0 | 0 | 0 | 0 | 1 | clean |
| fuse-overlayfs | 0 | 0 | 0 | 0 | 0 | clean |
| proot | 0 | 0 | 0 | 0 | 0 | clean |
| flatpak | 0 | 0 | 0 | 0 | 0 | clean |
| systemd | 0 | 0 | 0 | 0 | 5 | clean |
The remaining 14 projects (containerd, moby, podman, buildah, apptainer, singularity, gvisor, rootlesskit, youki, firecracker, kata, udocker, distrobox, sysbox) are Go/Rust/Shell and are listed for coverage; their mount logic is not C-analyzeable by this tool (see paper Section 7 for the language-agnostic runtime protocol that closes this gap).
Note: criu's single high finding is in test/zdtm/static/mnt_tracefs.c, a
ZDTM test harness, not production code; it is therefore classified candidate,
matching the paper.
run_experiments.sh writes one CSV per scenario into results/:
| File | Columns |
|---|---|
| scenario_a.csv | variant,iteration,before,after,leaked |
| scenario_b.csv | depth,iteration,before,after,leaked |
| scenario_c.csv | mode,iteration,before,after,leaked |
| scenario_d.csv | concurrent,iteration,before,after,leaked |
| state_leak_leak.csv | op,fds,inotify_watches,keyring_keys,cgroup_dirs,zombie_children |
| state_leak_fixed.csv | same as above |
| audit_results.csv | project,primary_language,analyzed,recursive_bind_sites,protected_sites,high_findings,medium_candidate_files,dynamic_flag_calls,verdict |
before/after are the per-iteration host mount counts captured from
/proc/self/mountinfo; leaked = after - before.
After running experiments, compare with expected/:
diff results/scenario_a.csv expected/scenario_a.csvThe before/after absolute counts are host-dependent (they depend on the
pre-existing mount table), so exact diffs are expected to differ. The key
patterns must match:
- Scenario A: buggy=1.0, fixed=0.0
- Scenario B: constant 1.0 across all depths
- Scenario C: shared=1.0, slave=0.0, fixed=0.0
- Scenario D: linear (1/2/4/8)
- State leak: leaky grows monotonically, fixed stays flat
- Audit: verdict column matches
expected/audit_results.csv
Ensure you're running as root:
sudo bash run_experiments.shIf the mount table grows too large (safety stop triggers above 15,000 mounts), reboot the system:
sudo rebootEnsure gcc is installed:
sudo apt-get install gccIf you use this artifact, please cite:
[Anonymous], "Measurement-Driven Non-Idempotency: Detecting Latent State-Leak
Faults in Linux Isolation Tools," in Proc. USENIX Security 2027.
This artifact is provided for evaluation purposes only.