Bugs Rust Won't Catch
4 hours ago
- #Rust Security
- #TOCTOU Bugs
- #Systems Programming
- Canonical disclosed 44 CVEs in uutils in April 2026, from an external audit ahead of Ubuntu 26.04 LTS.
- All bugs occurred in production Rust code written by experienced developers, evading borrow checker, clippy lints, and cargo audit.
- The largest bug cluster involved TOCTOU issues: checking and acting on a path across two syscalls allows attackers to swap paths via symlinks.
- Case study: CVE-2026-35355 in install where fs::remove_file followed by File::create could overwrite system files via symlink.
- Fix: Use OpenOptions::create_new(true) to guarantee new files or anchor operations on a file descriptor instead of path.
- Setting permissions after creation creates a security window; use OpenOptions::mode or DirBuilderExt::mode at creation time.
- String equality on paths doesn't ensure filesystem identity; use fs::canonicalize to resolve symlinks and compare paths properly.
- Rust's UTF-8 String/&str can corrupt Unix byte data (e.g., paths, env vars); use OsStr or &[u8] for systems code.
- Case study: CVE-2026-35346 in comm where String::from_utf8_lossy corrupted binary input; fix: use Write::write_all for raw bytes.
- Panics from unwrap/expect on untrusted input can cause denial of service; use error handling (?, checked_*) instead.
- Propagate errors fully; discarding Results with .ok() can hide failures (e.g., in chmod -R or dd).
- Bug-for-bug compatibility with original tools (e.g., GNU coreutils) is a security feature to avoid breaking scripts.
- Resolve inputs before crossing trust boundaries (e.g., CVE-2026-35368 in chroot where loading libraries after chroot led to code execution).
- Rust prevented memory-safety bugs (buffer overflows, use-after-free, data races) common in C codebases like GNU coreutils.
- Idiomatic Rust includes correctness: using file descriptors, OsStr, error handling, and respecting system realities.