mirror of
https://github.com/storytold/lightcraft.git
synced 2026-11-13 17:31:09 -06:00
security(lensdb): refuse a non-regular *.xml before opening it (opening a FIFO blocks)
The pathname is checked before File::open as well as the opened file after it: File::open on a FIFO blocks until a writer appears, so the post-open check alone never ran for one. Adds a unix regression test that hung before the fix.
This commit is contained in:
@@ -280,7 +280,11 @@ fn exif_focal_range(exif: &[String]) -> Option<(f64, f64)> {
|
||||
fn read_capped(path: &Path) -> Result<String, Error> {
|
||||
use std::io::Read;
|
||||
let io = |e: std::io::Error| Error::Io(e.to_string());
|
||||
// the opened file is checked, not the pathname: a link or FIFO swapped in after a pathname check is refused too
|
||||
// the pathname is checked before opening (opening a FIFO for reading blocks until a writer appears), then the
|
||||
// opened file again: a link or FIFO swapped in after the pathname check is refused too
|
||||
if !std::fs::metadata(path).map_err(io)?.is_file() {
|
||||
return Err(Error::Io(format!("{}: not a regular file", path.display())));
|
||||
}
|
||||
let file = std::fs::File::open(path).map_err(io)?;
|
||||
let meta = file.metadata().map_err(io)?;
|
||||
if !meta.is_file() {
|
||||
|
||||
@@ -417,3 +417,21 @@ fn load_dir_refuses_a_non_regular_xml_entry() {
|
||||
assert!(db.is_empty());
|
||||
assert_eq!(errs.len(), 1, "{errs:?}");
|
||||
}
|
||||
|
||||
/// A FIFO named `*.xml` is refused without opening it: opening a FIFO for reading blocks until a writer appears.
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
fn load_dir_refuses_a_fifo_without_blocking() {
|
||||
let dir = std::env::temp_dir().join(format!("lensdb-test-fifo-{}", std::process::id()));
|
||||
std::fs::create_dir(&dir).unwrap();
|
||||
let fifo = dir.join("f.xml");
|
||||
let made = std::process::Command::new("mkfifo").arg(&fifo).status().is_ok_and(|s| s.success());
|
||||
if !made {
|
||||
std::fs::remove_dir_all(&dir).unwrap();
|
||||
return;
|
||||
}
|
||||
let (db, errs) = LensDb::load_dir(&dir).unwrap();
|
||||
std::fs::remove_dir_all(&dir).unwrap();
|
||||
assert!(db.is_empty());
|
||||
assert_eq!(errs.len(), 1, "{errs:?}");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user