Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Artifact Evaluation Package

USENIX Security 2027: Measurement-Driven Non-Idempotency

Overview

This artifact accompanies the USENIX Security 2027 submission Measurement-Driven Non-Idempotency: Detecting Latent State-Leak Faults in Linux Isolation Tools. It provides:

  1. The measurement-driven non-idempotency framework (definitions + protocol)
  2. Formal model of the mount-propagation defect class
  3. Automated fault-injection campaign (four scenarios + a five-class state-leak generalization)
  4. A tree-sitter static analyzer for the mount-propagation defect class
  5. An ecosystem audit of 30 real isolation-related projects
  6. 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.

Requirements

  • 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)

Quick Start

# 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.md

Directory Structure

artifact/
├── 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

Experiments

Scenario A: Buggy vs Fixed Pivot (20 iterations each)

Tests the core defect: recursive bind mount without MS_PRIVATE.

  • Buggy: 1.0 leaks/invocation
  • Fixed: 0.0 leaks/invocation

Scenario B: Mount-Table Depth Scaling (5 iterations each)

Tests how leak rate scales with pre-existing mount depth (0/5/10/15/20).

  • Expected: constant 1.0 leak/invocation (fresh namespaces)

Scenario C: Propagation Type (10 iterations each)

Tests defect manifestation across propagation types.

  • Buggy (shared): 1.0, slave: 0.0, fixed (private): 0.0

Scenario D: Concurrent Invocations (5 iterations each)

Tests leak scaling with 1/2/4/8 concurrent processes.

  • Expected: linear (each process leaks independently)

State-Leak Generalization

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

Static Analysis

The tree-sitter analyzer detects the mount-propagation defect class in C/C++ source:

python3 src/analyzer.py /path/to/project --project name --json

It 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.

Ecosystem Audit (30 projects, 16 C/C++ analyzed)

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.

Results Format

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.

Verification

After running experiments, compare with expected/:

diff results/scenario_a.csv expected/scenario_a.csv

The 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

Troubleshooting

"Operation not permitted"

Ensure you're running as root:

sudo bash run_experiments.sh

Mount table overflow

If the mount table grows too large (safety stop triggers above 15,000 mounts), reboot the system:

sudo reboot

Compilation errors

Ensure gcc is installed:

sudo apt-get install gcc

Citation

If 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.

License

This artifact is provided for evaluation purposes only.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages