From 3367797b6df8287321587f45ba908753397f1482 Mon Sep 17 00:00:00 2001 From: emilylange Date: Tue, 14 Oct 2025 23:50:15 +0200 Subject: [PATCH] music-assistant: fix running the built-in snapcast server This patch fixes two issues that would otherwise prevent the built-in snapserver to run. Running music-assistant with an external snapserver is not affected by those. 1. snapserver prior to v0.30.0 allowed arbitrary code execution in the AddStream (and RemoveStream) JSON RPC API method that music-assistant uses to load a custom control script (plugin). To fix this rather severe vulnerability, snapserver v0.30.0 removed those affected methods altogether, only for them to return with new security measures in v0.31.0. Most relevant for us and this patch, the control script must be located in the [stream].plugin_dir now, which is unset by default. So to be able to load the control script music-assistant uses for the built-in snapserver, we simply pass --stream.plugin_dir with the correct directory as parameter when starting snapserver 2. snapserver exits with an error message on start up when it cannot read the configuration file since v0.32.0. To fix this, we tell snapserver to read /dev/null as config instead of the default (non-existent) /etc/snapserver.conf --- .../builtin-snapcast-server.patch | 33 +++++++++++++++++++ pkgs/by-name/mu/music-assistant/package.nix | 3 ++ 2 files changed, 36 insertions(+) create mode 100644 pkgs/by-name/mu/music-assistant/builtin-snapcast-server.patch diff --git a/pkgs/by-name/mu/music-assistant/builtin-snapcast-server.patch b/pkgs/by-name/mu/music-assistant/builtin-snapcast-server.patch new file mode 100644 index 000000000000..d58183f3dffb --- /dev/null +++ b/pkgs/by-name/mu/music-assistant/builtin-snapcast-server.patch @@ -0,0 +1,33 @@ +diff --git a/music_assistant/providers/snapcast/__init__.py b/music_assistant/providers/snapcast/__init__.py +index 742d798183ec6fd1ac1fdbcad750912c222de5c3..8d0d95577d31f735977884280b08f384187774bd 100644 +--- a/music_assistant/providers/snapcast/__init__.py ++++ b/music_assistant/providers/snapcast/__init__.py +@@ -87,7 +87,8 @@ DEFAULT_SNAPSTREAM_IDLE_THRESHOLD = 60000 + MASS_STREAM_PREFIX = "Music Assistant - " + MASS_ANNOUNCEMENT_POSTFIX = " (announcement)" + SNAPWEB_DIR = pathlib.Path(__file__).parent.resolve().joinpath("snapweb") +-CONTROL_SCRIPT = pathlib.Path(__file__).parent.resolve().joinpath("control.py") ++CONTROL_SCRIPT_DIR = pathlib.Path(__file__).parent.resolve() ++CONTROL_SCRIPT = CONTROL_SCRIPT_DIR.joinpath("control.py") + + DEFAULT_SNAPCAST_FORMAT = AudioFormat( + content_type=ContentType.PCM_S16LE, +@@ -866,6 +867,10 @@ class SnapCastProvider(PlayerProvider): + + args = [ + "snapserver", ++ # defaults to /etc/snapcast.conf but needs ++ # to exist in order for snapserver to start ++ # https://github.com/badaix/snapcast/issues/1402 ++ "--config=/dev/null", + # config settings taken from + # https://raw.githubusercontent.com/badaix/snapcast/86cd4b2b63e750a72e0dfe6a46d47caf01426c8d/server/etc/snapserver.conf + f"--server.datadir={self.mass.storage_path}", +@@ -878,6 +883,7 @@ class SnapCastProvider(PlayerProvider): + f"--stream.buffer={self._snapcast_server_buffer_size}", + f"--stream.chunk_ms={self._snapcast_server_chunk_ms}", + f"--stream.codec={self._snapcast_server_transport_codec}", ++ f"--stream.plugin_dir={CONTROL_SCRIPT_DIR}", + f"--stream.send_to_muted={str(self._snapcast_server_send_to_muted).lower()}", + f"--streaming_client.initial_volume={self._snapcast_server_initial_volume}", + ] diff --git a/pkgs/by-name/mu/music-assistant/package.nix b/pkgs/by-name/mu/music-assistant/package.nix index 71fe4275b77a..4faee79f70f4 100644 --- a/pkgs/by-name/mu/music-assistant/package.nix +++ b/pkgs/by-name/mu/music-assistant/package.nix @@ -68,6 +68,9 @@ python.pkgs.buildPythonApplication rec { # Disable interactive dependency resolution, which clashes with the immutable Python environment ./dont-install-deps.patch + + # Fix running the built-in snapcast server + ./builtin-snapcast-server.patch ]; postPatch = ''