astrid-runtime/astrid · error
mount data has NUL
Error message
mount data has NUL
What it means
mount_overlay converts the overlayfs data option string (lowerdir=/upperdir=/workdir=...) to a CString for mount(2). If the assembled data string contains an embedded NUL byte, CString::new fails and the function returns InvalidInput 'mount data has NUL'.
Solutions
- Validate each layer path (lowerdir/upperdir/workdir) for NUL bytes before assembling the data string
- Since validate inputs are Paths, check as_os_str().as_bytes().contains(&0) upstream
- Reject NUL-containing paths at the workspace configuration boundary
- Log the data string (NUL-escaped) to find which layer path is bad
Example fix
// before
let data = format!("lowerdir={},upperdir={},workdir={}", lower, upper, work);
mount_overlay(target, &data)?;
// after
for p in [&lower, &upper, &work] {
if p.as_os_str().as_bytes().contains(&0) { return Err(...); }
}
mount_overlay(target, &data)?; Defensive patterns
Strategy: validation
Validate before calling
for p in [&lower, &upper, &work] { if p.as_os_str().as_bytes().contains(&0) { return Err(io::Error::new(io::ErrorKind::InvalidInput, "layer path contains NUL")); } } Type guard
fn layer_ok(p: &Path) -> bool { !p.as_os_str().as_bytes().contains(&0) } Try / catch
match mount(target, &layers) { Err(e) if e.kind() == io::ErrorKind::InvalidInput => { /* inspect layer paths for NUL, fail the workspace setup */ }, other => other, } Prevention
- Validate every layer directory path before assembling the overlayfs data string
- Keep layer paths sourced from typed config, not raw bytes
- Log the data string NUL-escaped when mount fails for diagnosis
When it happens
Trigger: Calling mount (→ mount_overlay) when the data string built from layer directory paths contains an interior '\0' — i.e. one of the layer paths fed into the option string contains NUL.
Common situations: Layer/workspace paths derived from binary data or untrimmed buffers; corrupted configuration supplying layer directories with embedded NULs.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- mount target has NUL
- mount source has NUL
- umount target has NUL
- xattr name has NUL
- cannot unmount a relative mountpoint
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/e14b9577bfa11d43.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-vfs/src/workspace_cow/overlayfs.rs:500
fn path_hash(path: &Path) -> String {
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
let key = std::fs::canonicalize(path).unwrap_or_else(|_| path.to_path_buf());
let mut hasher = DefaultHasher::new();
key.hash(&mut hasher);
format!("{:016x}", hasher.finish())
}
/// `mount("overlay", target, "overlay", 0, data)`.
fn mount_overlay(target: &Path, data: &str) -> io::Result<()> {
let src = CString::new("overlay")
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "mount source has NUL"))?;
let fstype = CString::new("overlay")
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "mount fstype has NUL"))?;
let target_c = CString::new(target.as_os_str().as_bytes())
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "mount target has NUL"))?;
let data_c = CString::new(data)
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "mount data has NUL"))?;
// SAFETY: all four pointers are valid, NUL-terminated C strings that outlive
// the call; `mount` reads them and returns a status code, retaining no
// pointers. `data` is the overlayfs option string.
let rc = unsafe {
libc::mount(
src.as_ptr(),
target_c.as_ptr(),
fstype.as_ptr(),
0,
data_c.as_ptr().cast(),
)
};
if rc != 0 {
return Err(io::Error::last_os_error());
}
Ok(())
}
View on GitHub (pinned to affd8760f4)