From b01b70fc20f334d5060f14799bca7687eaeafd77 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Fri, 28 Feb 2025 11:14:52 -0800 Subject: [PATCH] reject overlapping media and database paths --- src/config.rs | 22 +++++++++++++++++++ src/error.rs | 6 +++++ tests/integrations/check_config.rs | 18 +++++++++++++++ .../check_config/database-in-media.toml | 12 ++++++++++ .../fixtures/check_config/dirs/a/.gitignore | 2 ++ .../fixtures/check_config/dirs/b/.gitignore | 2 ++ .../fixtures/check_config/dirs/c/a/.gitignore | 2 ++ .../fixtures/check_config/equal-paths.toml | 12 ++++++++++ .../check_config/media-in-database.toml | 12 ++++++++++ .../fixtures/check_config/minimal-valid.toml | 4 ++-- .../fixtures/check_config/valid.toml | 4 ++-- ...verlapping_paths_database@status_code.snap | 7 ++++++ ...ig__overlapping_paths_database@stderr.snap | 6 +++++ ...ig__overlapping_paths_database@stdout.snap | 5 +++++ ...__overlapping_paths_equal@status_code.snap | 7 ++++++ ...onfig__overlapping_paths_equal@stderr.snap | 6 +++++ ...onfig__overlapping_paths_equal@stdout.snap | 5 +++++ ...__overlapping_paths_media@status_code.snap | 7 ++++++ ...onfig__overlapping_paths_media@stderr.snap | 6 +++++ ...onfig__overlapping_paths_media@stdout.snap | 5 +++++ 20 files changed, 146 insertions(+), 4 deletions(-) create mode 100644 tests/integrations/fixtures/check_config/database-in-media.toml create mode 100644 tests/integrations/fixtures/check_config/dirs/a/.gitignore create mode 100644 tests/integrations/fixtures/check_config/dirs/b/.gitignore create mode 100644 tests/integrations/fixtures/check_config/dirs/c/a/.gitignore create mode 100644 tests/integrations/fixtures/check_config/equal-paths.toml create mode 100644 tests/integrations/fixtures/check_config/media-in-database.toml create mode 100644 tests/integrations/snapshots/integrations__check_config__overlapping_paths_database@status_code.snap create mode 100644 tests/integrations/snapshots/integrations__check_config__overlapping_paths_database@stderr.snap create mode 100644 tests/integrations/snapshots/integrations__check_config__overlapping_paths_database@stdout.snap create mode 100644 tests/integrations/snapshots/integrations__check_config__overlapping_paths_equal@status_code.snap create mode 100644 tests/integrations/snapshots/integrations__check_config__overlapping_paths_equal@stderr.snap create mode 100644 tests/integrations/snapshots/integrations__check_config__overlapping_paths_equal@stdout.snap create mode 100644 tests/integrations/snapshots/integrations__check_config__overlapping_paths_media@status_code.snap create mode 100644 tests/integrations/snapshots/integrations__check_config__overlapping_paths_media@stderr.snap create mode 100644 tests/integrations/snapshots/integrations__check_config__overlapping_paths_media@stdout.snap diff --git a/src/config.rs b/src/config.rs index 951fd41a..03487ace 100644 --- a/src/config.rs +++ b/src/config.rs @@ -538,5 +538,27 @@ where return Err(Error::RegistrationTokenEmpty); } + match &config.media.backend { + MediaBackendConfig::Filesystem(x) => { + let media_path = x + .path + .canonicalize() + .map_err(|e| Error::Canonicalize(e, x.path.clone()))?; + + let database_path = + config.database.path.canonicalize().map_err(|e| { + 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 { + return Err(Error::DatabaseMediaOverlap); + } + } + } + Ok(config) } diff --git a/src/error.rs b/src/error.rs index ce8ebb37..49cf7307 100644 --- a/src/error.rs +++ b/src/error.rs @@ -134,8 +134,14 @@ pub(crate) enum Config { #[error("failed to parse configuration file {1:?}")] Parse(#[source] toml::de::Error, PathBuf), + #[error("failed to canonicalize path {}", .1.display())] + Canonicalize(#[source] std::io::Error, PathBuf), + #[error("registration token must not be empty")] RegistrationTokenEmpty, + + #[error("database and media paths overlap")] + DatabaseMediaOverlap, } /// Errors that can occur while searching for a config file diff --git a/tests/integrations/check_config.rs b/tests/integrations/check_config.rs index 03474266..7db366e8 100644 --- a/tests/integrations/check_config.rs +++ b/tests/integrations/check_config.rs @@ -93,3 +93,21 @@ make_snapshot_test!( "A config with invalid values fails", "invalid-values.toml", ); + +make_snapshot_test!( + overlapping_paths_equal, + "A config with equal paths fails", + "equal-paths.toml", +); + +make_snapshot_test!( + overlapping_paths_media, + "A config with the media path inside the database path fails", + "media-in-database.toml", +); + +make_snapshot_test!( + overlapping_paths_database, + "A config with the database path inside the media path fails", + "database-in-media.toml", +); diff --git a/tests/integrations/fixtures/check_config/database-in-media.toml b/tests/integrations/fixtures/check_config/database-in-media.toml new file mode 100644 index 00000000..db50a5b8 --- /dev/null +++ b/tests/integrations/fixtures/check_config/database-in-media.toml @@ -0,0 +1,12 @@ +server_name = "example.com" + +[server_discovery] +client.base_url = "https://matrix.example.com" + +[database] +backend = "rocksdb" +path = "tests/integrations/fixtures/check_config/dirs/c/a" + +[media.backend] +type = "filesystem" +path = "tests/integrations/fixtures/check_config/dirs/c" diff --git a/tests/integrations/fixtures/check_config/dirs/a/.gitignore b/tests/integrations/fixtures/check_config/dirs/a/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/tests/integrations/fixtures/check_config/dirs/a/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/integrations/fixtures/check_config/dirs/b/.gitignore b/tests/integrations/fixtures/check_config/dirs/b/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/tests/integrations/fixtures/check_config/dirs/b/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/integrations/fixtures/check_config/dirs/c/a/.gitignore b/tests/integrations/fixtures/check_config/dirs/c/a/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/tests/integrations/fixtures/check_config/dirs/c/a/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/integrations/fixtures/check_config/equal-paths.toml b/tests/integrations/fixtures/check_config/equal-paths.toml new file mode 100644 index 00000000..1271b2d3 --- /dev/null +++ b/tests/integrations/fixtures/check_config/equal-paths.toml @@ -0,0 +1,12 @@ +server_name = "example.com" + +[server_discovery] +client.base_url = "https://matrix.example.com" + +[database] +backend = "rocksdb" +path = "tests/integrations/fixtures/check_config/dirs/a" + +[media.backend] +type = "filesystem" +path = "tests/integrations/fixtures/check_config/dirs/a" diff --git a/tests/integrations/fixtures/check_config/media-in-database.toml b/tests/integrations/fixtures/check_config/media-in-database.toml new file mode 100644 index 00000000..66e94257 --- /dev/null +++ b/tests/integrations/fixtures/check_config/media-in-database.toml @@ -0,0 +1,12 @@ +server_name = "example.com" + +[server_discovery] +client.base_url = "https://matrix.example.com" + +[database] +backend = "rocksdb" +path = "tests/integrations/fixtures/check_config/dirs/c" + +[media.backend] +type = "filesystem" +path = "tests/integrations/fixtures/check_config/dirs/c/a" diff --git a/tests/integrations/fixtures/check_config/minimal-valid.toml b/tests/integrations/fixtures/check_config/minimal-valid.toml index 3c114f2e..330e0d57 100644 --- a/tests/integrations/fixtures/check_config/minimal-valid.toml +++ b/tests/integrations/fixtures/check_config/minimal-valid.toml @@ -5,8 +5,8 @@ client.base_url = "https://matrix.example.com" [database] backend = "rocksdb" -path = "/var/lib/grapevine/database" +path = "tests/integrations/fixtures/check_config/dirs/a" [media.backend] type = "filesystem" -path = "/var/lib/grapevine/media" +path = "tests/integrations/fixtures/check_config/dirs/b" diff --git a/tests/integrations/fixtures/check_config/valid.toml b/tests/integrations/fixtures/check_config/valid.toml index 6b6e1a3d..cb0fda11 100644 --- a/tests/integrations/fixtures/check_config/valid.toml +++ b/tests/integrations/fixtures/check_config/valid.toml @@ -10,11 +10,11 @@ client.base_url = "https://matrix.example.com" [database] backend = "rocksdb" -path = "/var/lib/grapevine/database" +path = "tests/integrations/fixtures/check_config/dirs/a" [media.backend] type = "filesystem" -path = "/var/lib/grapevine/media" +path = "tests/integrations/fixtures/check_config/dirs/b" [federation] enable = true diff --git a/tests/integrations/snapshots/integrations__check_config__overlapping_paths_database@status_code.snap b/tests/integrations/snapshots/integrations__check_config__overlapping_paths_database@status_code.snap new file mode 100644 index 00000000..d2d33fe4 --- /dev/null +++ b/tests/integrations/snapshots/integrations__check_config__overlapping_paths_database@status_code.snap @@ -0,0 +1,7 @@ +--- +source: tests/integrations/check_config.rs +description: A config with the database path inside the media path fails +--- +Some( + 1, +) diff --git a/tests/integrations/snapshots/integrations__check_config__overlapping_paths_database@stderr.snap b/tests/integrations/snapshots/integrations__check_config__overlapping_paths_database@stderr.snap new file mode 100644 index 00000000..8b550414 --- /dev/null +++ b/tests/integrations/snapshots/integrations__check_config__overlapping_paths_database@stderr.snap @@ -0,0 +1,6 @@ +--- +source: tests/integrations/check_config.rs +description: A config with the database path inside the media path fails +--- +Error: failed to validate configuration + Caused by: database and media paths overlap diff --git a/tests/integrations/snapshots/integrations__check_config__overlapping_paths_database@stdout.snap b/tests/integrations/snapshots/integrations__check_config__overlapping_paths_database@stdout.snap new file mode 100644 index 00000000..065d47d1 --- /dev/null +++ b/tests/integrations/snapshots/integrations__check_config__overlapping_paths_database@stdout.snap @@ -0,0 +1,5 @@ +--- +source: tests/integrations/check_config.rs +description: A config with the database path inside the media path fails +--- + diff --git a/tests/integrations/snapshots/integrations__check_config__overlapping_paths_equal@status_code.snap b/tests/integrations/snapshots/integrations__check_config__overlapping_paths_equal@status_code.snap new file mode 100644 index 00000000..ac822b67 --- /dev/null +++ b/tests/integrations/snapshots/integrations__check_config__overlapping_paths_equal@status_code.snap @@ -0,0 +1,7 @@ +--- +source: tests/integrations/check_config.rs +description: A config with equal paths fails +--- +Some( + 1, +) diff --git a/tests/integrations/snapshots/integrations__check_config__overlapping_paths_equal@stderr.snap b/tests/integrations/snapshots/integrations__check_config__overlapping_paths_equal@stderr.snap new file mode 100644 index 00000000..c1e68376 --- /dev/null +++ b/tests/integrations/snapshots/integrations__check_config__overlapping_paths_equal@stderr.snap @@ -0,0 +1,6 @@ +--- +source: tests/integrations/check_config.rs +description: A config with equal paths fails +--- +Error: failed to validate configuration + Caused by: database and media paths overlap diff --git a/tests/integrations/snapshots/integrations__check_config__overlapping_paths_equal@stdout.snap b/tests/integrations/snapshots/integrations__check_config__overlapping_paths_equal@stdout.snap new file mode 100644 index 00000000..acbd1296 --- /dev/null +++ b/tests/integrations/snapshots/integrations__check_config__overlapping_paths_equal@stdout.snap @@ -0,0 +1,5 @@ +--- +source: tests/integrations/check_config.rs +description: A config with equal paths fails +--- + diff --git a/tests/integrations/snapshots/integrations__check_config__overlapping_paths_media@status_code.snap b/tests/integrations/snapshots/integrations__check_config__overlapping_paths_media@status_code.snap new file mode 100644 index 00000000..5240e180 --- /dev/null +++ b/tests/integrations/snapshots/integrations__check_config__overlapping_paths_media@status_code.snap @@ -0,0 +1,7 @@ +--- +source: tests/integrations/check_config.rs +description: A config with the media path inside the database path fails +--- +Some( + 1, +) diff --git a/tests/integrations/snapshots/integrations__check_config__overlapping_paths_media@stderr.snap b/tests/integrations/snapshots/integrations__check_config__overlapping_paths_media@stderr.snap new file mode 100644 index 00000000..2402b8b4 --- /dev/null +++ b/tests/integrations/snapshots/integrations__check_config__overlapping_paths_media@stderr.snap @@ -0,0 +1,6 @@ +--- +source: tests/integrations/check_config.rs +description: A config with the media path inside the database path fails +--- +Error: failed to validate configuration + Caused by: database and media paths overlap diff --git a/tests/integrations/snapshots/integrations__check_config__overlapping_paths_media@stdout.snap b/tests/integrations/snapshots/integrations__check_config__overlapping_paths_media@stdout.snap new file mode 100644 index 00000000..8d4c65a1 --- /dev/null +++ b/tests/integrations/snapshots/integrations__check_config__overlapping_paths_media@stdout.snap @@ -0,0 +1,5 @@ +--- +source: tests/integrations/check_config.rs +description: A config with the media path inside the database path fails +--- +