run: Interpret tcp: addresses for PulseAudio

Put the configured server address string in PULSE_SERVER if it appears
to be remote. This should be enough for apps that already have network
access via --share=network.

If remote access to a PulseAudio server has been selected but the app
does not already have the --share=network permission, we don't want to
add --share=network automatically, because that would open up the app's
access to network resources, perhaps unexpectedly. However, users of
this non-default configuration can use `flatpak run --share=network` or
`flatpak override --share=network` to open up that access if they
consider it to be safe enough.

Resolves: https://github.com/flatpak/flatpak/issues/3908
Signed-off-by: Simon McVittie <smcv@collabora.com>
(cherry picked from commit ee418c1f2010b0ffa5ad40c96a04d054eadce202)
This commit is contained in:
Simon McVittie 2022-01-26 16:53:50 +00:00 committed by Alexander Larsson
parent e49f5289bc
commit 3d67f4ec40

View File

@ -578,10 +578,12 @@ flatpak_run_get_pulseaudio_server (void)
/*
* Parse a PulseAudio server string, as documented on
* https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/ServerStrings/.
* Returns the first supported server address, or NULL if none are supported.
* Returns the first supported server address, or NULL if none are supported,
* or NULL with @remote set if @value points to a remote server.
*/
static char *
flatpak_run_parse_pulse_server (const char *value)
flatpak_run_parse_pulse_server (const char *value,
gboolean *remote)
{
g_auto(GStrv) servers = g_strsplit (value, " ", 0);
gsize i;
@ -606,7 +608,11 @@ flatpak_run_parse_pulse_server (const char *value)
if (server[0] == '/')
return g_strdup (server);
/* TODO: Support TCP connections? */
if (g_str_has_prefix (server, "tcp:"))
{
*remote = TRUE;
return NULL;
}
}
return NULL;
@ -721,16 +727,19 @@ flatpak_run_get_pulse_runtime_dir (void)
}
static void
flatpak_run_add_pulseaudio_args (FlatpakBwrap *bwrap)
flatpak_run_add_pulseaudio_args (FlatpakBwrap *bwrap,
FlatpakContextShares shares)
{
g_autofree char *pulseaudio_server = flatpak_run_get_pulseaudio_server ();
g_autofree char *pulseaudio_socket = NULL;
g_autofree char *pulse_runtime_dir = flatpak_run_get_pulse_runtime_dir ();
gboolean remote = FALSE;
if (pulseaudio_server)
pulseaudio_socket = flatpak_run_parse_pulse_server (pulseaudio_server);
pulseaudio_socket = flatpak_run_parse_pulse_server (pulseaudio_server,
&remote);
if (!pulseaudio_socket)
if (pulseaudio_socket == NULL && !remote)
{
pulseaudio_socket = g_build_filename (pulse_runtime_dir, "native", NULL);
@ -738,7 +747,7 @@ flatpak_run_add_pulseaudio_args (FlatpakBwrap *bwrap)
g_clear_pointer (&pulseaudio_socket, g_free);
}
if (!pulseaudio_socket)
if (pulseaudio_socket == NULL && !remote)
{
pulseaudio_socket = realpath ("/var/run/pulse/native", NULL);
@ -748,7 +757,18 @@ flatpak_run_add_pulseaudio_args (FlatpakBwrap *bwrap)
flatpak_bwrap_unset_env (bwrap, "PULSE_SERVER");
if (pulseaudio_socket && g_file_test (pulseaudio_socket, G_FILE_TEST_EXISTS))
if (remote)
{
if ((shares & FLATPAK_CONTEXT_SHARED_NETWORK) == 0)
{
g_warning ("Remote PulseAudio server configured.");
g_warning ("PulseAudio access will require --share=network permission.");
}
g_debug ("Using remote PulseAudio server \"%s\"", pulseaudio_server);
flatpak_bwrap_set_env (bwrap, "PULSE_SERVER", pulseaudio_server, TRUE);
}
else if (pulseaudio_socket && g_file_test (pulseaudio_socket, G_FILE_TEST_EXISTS))
{
static const char sandbox_socket_path[] = "/run/flatpak/pulse/native";
static const char pulse_server[] = "unix:/run/flatpak/pulse/native";
@ -776,7 +796,7 @@ flatpak_run_add_pulseaudio_args (FlatpakBwrap *bwrap)
* since we don't want to add more permissions for something we plan to replace with
* portals/pipewire going forward we reinterpret pulseaudio to also mean ALSA.
*/
if (g_file_test ("/dev/snd", G_FILE_TEST_IS_DIR))
if (!remote && g_file_test ("/dev/snd", G_FILE_TEST_IS_DIR))
flatpak_bwrap_add_args (bwrap, "--dev-bind", "/dev/snd", "/dev/snd", NULL);
}
@ -1634,7 +1654,7 @@ flatpak_run_add_environment_args (FlatpakBwrap *bwrap,
if (context->sockets & FLATPAK_CONTEXT_SOCKET_PULSEAUDIO)
{
g_debug ("Allowing pulseaudio access");
flatpak_run_add_pulseaudio_args (bwrap);
flatpak_run_add_pulseaudio_args (bwrap, context->shares);
}
if (context->sockets & FLATPAK_CONTEXT_SOCKET_PCSC)