proc-canonicalize
A patch for std::fs::canonicalize that preserves Linux /proc/PID/root namespace boundaries.
The Problem
On Linux, /proc/PID/root is a "magic symlink" that crosses into a process's mount namespace. When you access files through it, you're accessing the container's filesystem:
# Reading a container's file from the host:
However, std::fs::canonicalize resolves this magic symlink to /, breaking security boundaries:
use PathBuf;
// BROKEN: std::fs::canonicalize loses the namespace prefix!
let resolved = canonicalize?;
assert_eq!; // Resolves to "/" - host root!
The Fix
This crate preserves the /proc/PID/root and /proc/PID/cwd prefixes:
use canonicalize;
use PathBuf;
// FIXED: Namespace prefix is preserved!
let resolved = canonicalize?;
assert_eq!;
// Paths through the boundary also preserve the prefix
let resolved = canonicalize?;
assert!;
Normal paths work exactly like std::fs::canonicalize:
use canonicalize;
let std_result = canonicalize?;
let our_result = canonicalize?;
assert_eq!;
Use Case
Container monitoring and security tools that need to:
- Access container filesystems from the host via
/proc/PID/root - Validate that paths stay within the container boundary
- Prevent container escape vulnerabilities
use canonicalize;
Supported Paths
| Path Pattern | Preserved |
|---|---|
/proc/PID/root |
✅ |
/proc/PID/root/... |
✅ |
/proc/PID/cwd |
✅ |
/proc/PID/cwd/... |
✅ |
/proc/self/root |
✅ |
/proc/self/cwd |
✅ |
/proc/thread-self/root |
✅ |
/proc/thread-self/cwd |
✅ |
| All other paths | Same as std::fs::canonicalize |
Platform Support
- Linux: Full functionality
- Other platforms: Falls back to
std::fs::canonicalize(no-op)
Optional Features
dunce (Windows Only)
Simplifies Windows extended-length paths by removing the \\?\ prefix when possible:
[]
= { = "0.0.3", = ["dunce"] }
Behavior:
- Without
dunce: Returns\\?\C:\Users\Alice\file.txt(Windows extended-length format) - With
dunce: ReturnsC:\Users\Alice\file.txt(simplified format)
Benefits:
- ✅ More readable paths in logs and user output
- ✅ Automatically preserves
\\?\prefix when needed (e.g., for paths longer than 260 characters)
Zero Dependencies
This crate has no dependencies beyond the Rust standard library.
Installation
[]
= "0.0.3"
License
MIT OR Apache-2.0