From 50583bc93ef948e450112c36dc159151a0c06c41 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Fri, 21 Mar 2025 16:18:40 -0700 Subject: [PATCH] reject overlapping non-canonical paths too For example, if the database path is `/foo` and the media path is `/foo/bar`, but `/foo/bar` is a symlink or hardlink to `/baz`, the previous check would pass. The whole point of this check is to ensure that the database and media data can't step on each other, so this check is needed to deny that kind of situation as well. It would probably be good to add a test for this behavior. --- src/config.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/config.rs b/src/config.rs index 03487ace..0c1f2e55 100644 --- a/src/config.rs +++ b/src/config.rs @@ -540,6 +540,10 @@ where match &config.media.backend { MediaBackendConfig::Filesystem(x) => { + if overlap(&x.path, &config.database.path) { + return Err(Error::DatabaseMediaOverlap); + } + let media_path = x .path .canonicalize() @@ -550,11 +554,7 @@ where Error::Canonicalize(e, config.database.path.clone()) })?; - let overlap = media_path == database_path - || media_path.starts_with(&database_path) - || database_path.starts_with(&media_path); - - if overlap { + if overlap(&media_path, &database_path) { return Err(Error::DatabaseMediaOverlap); } } @@ -562,3 +562,8 @@ where Ok(config) } + +/// Returns `true` if two paths overlap. +fn overlap(a: &Path, b: &Path) -> bool { + a == b || a.starts_with(b) || b.starts_with(a) +}