From 06c23ab51b1e084c6d6f6c7ee3029c93822f6cda Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Sat, 7 Nov 2026 12:46:04 -0600 Subject: [PATCH] resolve the full ffmpeg path under granular root --- frigate/test/test_ffmpeg_path_resolution.py | 7 +++++++ frigate/util/config.py | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) 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