diff --git a/frigate/test/test_ffmpeg_path_resolution.py b/frigate/test/test_ffmpeg_path_resolution.py index b6ea9b6fcc..02ae196044 100644 --- a/frigate/test/test_ffmpeg_path_resolution.py +++ b/frigate/test/test_ffmpeg_path_resolution.py @@ -216,6 +216,13 @@ class TestConfigFfmpegRootGuardSymlinks(unittest.TestCase): os.symlink(evil, self.link) self.assertEqual(self._resolve({"FRIGATE_ROOT_SERVICES": "frigate"}), BUNDLED) + def test_bin_linked_into_a_writable_tree_is_refused(self) -> None: + evil = os.path.join(self.writable, "evil") + os.makedirs(evil) + os.symlink(evil, os.path.join(self.root_owned, "bin")) + os.symlink(self.root_owned, self.link) + self.assertEqual(self._resolve({"FRIGATE_ROOT_SERVICES": "frigate"}), BUNDLED) + def test_unprivileged_service_keeps_the_path_as_written(self) -> None: os.symlink(self.root_owned, self.link) self.assertEqual(self._resolve({}), f"{self.link}/bin/ffmpeg") diff --git a/frigate/util/config.py b/frigate/util/config.py index aec731f489..634016a331 100644 --- a/frigate/util/config.py +++ b/frigate/util/config.py @@ -125,9 +125,9 @@ def resolve_ffmpeg_path( else: # return the resolved form so a link in the path cannot be retargeted # after the check - real = os.path.realpath(path) + real = os.path.realpath(f"{path}/bin/{binary}") if is_valid_ffmpeg_path(real) and not is_runtime_user_writable(real): - return f"{real}/bin/{binary}" + return real _warn_ignored_ffmpeg_path(path, service) version = DEFAULT_FFMPEG_VERSION