mirror of
https://github.com/flatpak/flatpak.git
synced 2026-04-04 15:15:25 -04:00
Add an option to share the pid namespace with the parent flatpak
As with flatpak run --parent-expose-pids, this will only work if we have a working, non-setuid bwrap. Systems where user namespace creation is restricted and bwrap needs to be setuid (Debian 10, RHEL/CentOS 7, Arch Linux linux-hardened kernel) will have degraded functionality. This option is similar to --expose-pids, except that instead of making the subsandbox use a nested pid namespace inside the parent's, it makes the subsandbox share the parent's pid namespace as-is, so that process IDs in the parent and the subsandbox are interchangeable. This will be useful if the parent and the subsandbox communicate via protocols that assume a global view of the process ID namespace, for example passing process IDs across an AF_UNIX socket or in shared memory. In particular, this will be useful for Steam's pressure-vessel container tool: the IPC between the Steam client and the "game overlay" loaded into Steam games uses process IDs, and becomes confused if they don't match up. This weakens the security boundary between a subsandbox and the parent, but that's OK in some cases, especially if the subsandbox is being used as a way to get a different runtime /usr (flatpak-spawn --latest-version or #4018) rather than as a security boundary. Signed-off-by: Simon McVittie <smcv@collabora.com>
This commit is contained in:
committed by
Alexander Larsson
parent
e5da98ff4b
commit
bbf6debec2
@@ -57,6 +57,7 @@ static char *opt_commit;
|
||||
static char *opt_runtime_commit;
|
||||
static int opt_parent_pid;
|
||||
static gboolean opt_parent_expose_pids;
|
||||
static gboolean opt_parent_share_pids;
|
||||
static int opt_instance_id_fd = -1;
|
||||
|
||||
static GOptionEntry options[] = {
|
||||
@@ -82,6 +83,7 @@ static GOptionEntry options[] = {
|
||||
{ "die-with-parent", 'p', 0, G_OPTION_ARG_NONE, &opt_die_with_parent, N_("Kill processes when the parent process dies"), NULL },
|
||||
{ "parent-pid", 0, 0, G_OPTION_ARG_INT, &opt_parent_pid, N_("Use PID as parent pid for sharing namespaces"), N_("PID") },
|
||||
{ "parent-expose-pids", 0, 0, G_OPTION_ARG_NONE, &opt_parent_expose_pids, N_("Make processes visible in parent namespace"), NULL },
|
||||
{ "parent-share-pids", 0, 0, G_OPTION_ARG_NONE, &opt_parent_share_pids, N_("Share process ID namespace with parent"), NULL },
|
||||
{ "instance-id-fd", 0, 0, G_OPTION_ARG_INT, &opt_instance_id_fd, N_("Write the instance ID to the given file descriptor"), NULL },
|
||||
{ NULL }
|
||||
};
|
||||
@@ -286,6 +288,8 @@ flatpak_builtin_run (int argc, char **argv, GCancellable *cancellable, GError **
|
||||
flags |= FLATPAK_RUN_FLAG_NO_DOCUMENTS_PORTAL;
|
||||
if (opt_parent_expose_pids)
|
||||
flags |= FLATPAK_RUN_FLAG_PARENT_EXPOSE_PIDS;
|
||||
if (opt_parent_share_pids)
|
||||
flags |= FLATPAK_RUN_FLAG_PARENT_SHARE_PIDS;
|
||||
if (!opt_a11y_bus)
|
||||
flags |= FLATPAK_RUN_FLAG_NO_A11Y_BUS_PROXY;
|
||||
if (!opt_session_bus)
|
||||
|
||||
@@ -48,6 +48,7 @@ typedef enum {
|
||||
FLATPAK_RUN_FLAG_DO_NOT_REAP = (1 << 18),
|
||||
FLATPAK_RUN_FLAG_NO_PROC = (1 << 19),
|
||||
FLATPAK_RUN_FLAG_PARENT_EXPOSE_PIDS = (1 << 20),
|
||||
FLATPAK_RUN_FLAG_PARENT_SHARE_PIDS = (1 << 21),
|
||||
} FlatpakRunFlags;
|
||||
|
||||
typedef struct FlatpakDir FlatpakDir;
|
||||
|
||||
@@ -2940,8 +2940,10 @@ flatpak_run_setup_base_argv (FlatpakBwrap *bwrap,
|
||||
"--proc", "/proc",
|
||||
NULL);
|
||||
|
||||
if (!(flags & FLATPAK_RUN_FLAG_PARENT_SHARE_PIDS))
|
||||
flatpak_bwrap_add_arg (bwrap, "--unshare-pid");
|
||||
|
||||
flatpak_bwrap_add_args (bwrap,
|
||||
"--unshare-pid",
|
||||
"--dir", "/tmp",
|
||||
"--dir", "/var/tmp",
|
||||
"--dir", "/run/host",
|
||||
@@ -3596,7 +3598,7 @@ flatpak_run_app (FlatpakDecomposed *app_ref,
|
||||
gboolean use_ld_so_cache = TRUE;
|
||||
gboolean sandboxed = (flags & FLATPAK_RUN_FLAG_SANDBOX) != 0;
|
||||
gboolean parent_expose_pids = (flags & FLATPAK_RUN_FLAG_PARENT_EXPOSE_PIDS) != 0;
|
||||
|
||||
gboolean parent_share_pids = (flags & FLATPAK_RUN_FLAG_PARENT_SHARE_PIDS) != 0;
|
||||
struct stat s;
|
||||
|
||||
if (!check_sudo (error))
|
||||
@@ -3911,7 +3913,7 @@ flatpak_run_app (FlatpakDecomposed *app_ref,
|
||||
if (cwd)
|
||||
flatpak_bwrap_add_args (bwrap, "--chdir", cwd, NULL);
|
||||
|
||||
if (parent_expose_pids)
|
||||
if (parent_expose_pids || parent_share_pids)
|
||||
{
|
||||
g_autofree char *userns_path = NULL;
|
||||
g_autofree char *pidns_path = NULL;
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
bus name org.freedesktop.portal.Flatpak and the object path
|
||||
/org/freedesktop/portal/Flatpak.
|
||||
|
||||
This documentation describes version 4 of this interface.
|
||||
This documentation describes version 5 of this interface.
|
||||
-->
|
||||
<interface name='org.freedesktop.portal.Flatpak'>
|
||||
<property name="version" type="u" access="read"/>
|
||||
@@ -49,7 +49,9 @@
|
||||
<varlistentry>
|
||||
<term>1 (FLATPAK_SPAWN_SUPPORT_FLAGS_EXPOSE_PIDS)</term>
|
||||
<listitem><para>
|
||||
Supports the expose sandbox pids flag of Spawn.
|
||||
Supports the expose sandbox pids flag of Spawn.
|
||||
If the version of this interface is 5 or later, this also
|
||||
indicates that the share sandbox pids flag is available.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
@@ -120,6 +122,17 @@
|
||||
This was added in version 4 of this interface (available from flatpak 1.8.0 and later).
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>128 (FLATPAK_SPAWN_FLAGS_SHARE_PIDS)</term>
|
||||
<listitem><para>
|
||||
Expose the sandbox process IDs in the caller's sandbox and
|
||||
the caller's process IDs in the new sandbox. Only supported
|
||||
if using user namespaces for containers (not setuid), see the
|
||||
support property.
|
||||
</para><para>
|
||||
This was added in version 5 of this interface (available from flatpak 1.10.0 and later).
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
Unknown (unsupported) flags are an error and will cause Spawn()
|
||||
@@ -246,7 +259,8 @@
|
||||
SpawnStarted:
|
||||
@pid: the PID of the process that has been started
|
||||
@relpid: the PID of the process relative to the current namespace.
|
||||
This is only non-zero if the expose PIDs flag (32) was passed to
|
||||
This is only non-zero if the expose PIDs flag (32) or the share
|
||||
PIDs flag (128) was passed to
|
||||
org.freedesktop.portal.Flatpak.Spawn(), and it may still be zero if
|
||||
the process exits before its relative PID could be read.
|
||||
|
||||
|
||||
@@ -563,7 +563,8 @@ key=v1;v2;
|
||||
<term><option>--parent-pid=PID</option></term>
|
||||
|
||||
<listitem><para>
|
||||
Specifies the pid of the "parent" flatpak, used by --parent-expose-pids.
|
||||
Specifies the pid of the "parent" flatpak, used by
|
||||
--parent-expose-pids and --parent-share-pids.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
@@ -576,6 +577,16 @@ key=v1;v2;
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--parent-share-pids</option></term>
|
||||
|
||||
<listitem><para>
|
||||
Use the same process ID namespace for the processes of
|
||||
the new sandbox and the sandbox of the parent flatpak, as
|
||||
defined by --parent-pid. Implies --parent-expose-pids.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--instance-id-fd</option></term>
|
||||
|
||||
|
||||
@@ -207,7 +207,7 @@ typedef struct
|
||||
char *client;
|
||||
guint child_watch;
|
||||
gboolean watch_bus;
|
||||
gboolean expose_pids;
|
||||
gboolean expose_or_share_pids;
|
||||
} PidData;
|
||||
|
||||
static void
|
||||
@@ -408,7 +408,7 @@ check_child_pid_status (void *user_data)
|
||||
}
|
||||
|
||||
/* Only send the child PID if it's exposed */
|
||||
if (pid_data->expose_pids)
|
||||
if (pid_data->expose_or_share_pids)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
relative_child_pid = get_child_pid_relative_to_parent_sandbox (child_pid, &error);
|
||||
@@ -779,6 +779,7 @@ handle_spawn (PortalFlatpak *object,
|
||||
guint sandbox_flags = 0;
|
||||
gboolean sandboxed;
|
||||
gboolean expose_pids;
|
||||
gboolean share_pids;
|
||||
gboolean notify_start;
|
||||
gboolean devel;
|
||||
|
||||
@@ -1047,7 +1048,9 @@ handle_spawn (PortalFlatpak *object,
|
||||
}
|
||||
|
||||
expose_pids = (arg_flags & FLATPAK_SPAWN_FLAGS_EXPOSE_PIDS) != 0;
|
||||
if (expose_pids)
|
||||
share_pids = (arg_flags & FLATPAK_SPAWN_FLAGS_SHARE_PIDS) != 0;
|
||||
|
||||
if (expose_pids || share_pids)
|
||||
{
|
||||
g_autofree char *instance_id = NULL;
|
||||
int sender_pid1 = 0;
|
||||
@@ -1056,7 +1059,7 @@ handle_spawn (PortalFlatpak *object,
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_NOT_SUPPORTED,
|
||||
"Expose pids not supported");
|
||||
"Expose pids not supported with setuid bwrap");
|
||||
return G_DBUS_METHOD_INVOCATION_HANDLED;
|
||||
}
|
||||
|
||||
@@ -1079,7 +1082,11 @@ handle_spawn (PortalFlatpak *object,
|
||||
}
|
||||
|
||||
g_ptr_array_add (flatpak_argv, g_strdup_printf ("--parent-pid=%d", sender_pid1));
|
||||
g_ptr_array_add (flatpak_argv, g_strdup ("--parent-expose-pids"));
|
||||
|
||||
if (share_pids)
|
||||
g_ptr_array_add (flatpak_argv, g_strdup ("--parent-share-pids"));
|
||||
else
|
||||
g_ptr_array_add (flatpak_argv, g_strdup ("--parent-expose-pids"));
|
||||
}
|
||||
|
||||
notify_start = (arg_flags & FLATPAK_SPAWN_FLAGS_NOTIFY_START) != 0;
|
||||
@@ -1278,7 +1285,7 @@ handle_spawn (PortalFlatpak *object,
|
||||
pid_data->pid = pid;
|
||||
pid_data->client = g_strdup (g_dbus_method_invocation_get_sender (invocation));
|
||||
pid_data->watch_bus = (arg_flags & FLATPAK_SPAWN_FLAGS_WATCH_BUS) != 0;
|
||||
pid_data->expose_pids = expose_pids;
|
||||
pid_data->expose_or_share_pids = (expose_pids || share_pids);
|
||||
pid_data->child_watch = g_child_watch_add_full (G_PRIORITY_DEFAULT,
|
||||
pid,
|
||||
child_watch_died,
|
||||
@@ -2679,7 +2686,7 @@ on_bus_acquired (GDBusConnection *connection,
|
||||
g_dbus_interface_skeleton_set_flags (G_DBUS_INTERFACE_SKELETON (portal),
|
||||
G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD);
|
||||
|
||||
portal_flatpak_set_version (PORTAL_FLATPAK (portal), 4);
|
||||
portal_flatpak_set_version (PORTAL_FLATPAK (portal), 5);
|
||||
portal_flatpak_set_supports (PORTAL_FLATPAK (portal), supports);
|
||||
|
||||
g_signal_connect (portal, "handle-spawn", G_CALLBACK (handle_spawn), NULL);
|
||||
|
||||
@@ -29,6 +29,7 @@ typedef enum {
|
||||
FLATPAK_SPAWN_FLAGS_WATCH_BUS = 1 << 4,
|
||||
FLATPAK_SPAWN_FLAGS_EXPOSE_PIDS = 1 << 5,
|
||||
FLATPAK_SPAWN_FLAGS_NOTIFY_START = 1 << 6,
|
||||
FLATPAK_SPAWN_FLAGS_SHARE_PIDS = 1 << 7,
|
||||
} FlatpakSpawnFlags;
|
||||
|
||||
typedef enum {
|
||||
@@ -44,13 +45,18 @@ typedef enum {
|
||||
FLATPAK_SPAWN_SUPPORT_FLAGS_EXPOSE_PIDS = 1 << 0,
|
||||
} FlatpakSpawnSupportFlags;
|
||||
|
||||
/* The same flag is reused: this feature is available under the same
|
||||
* circumstances */
|
||||
#define FLATPAK_SPAWN_SUPPORT_FLAGS_SHARE_PIDS FLATPAK_SPAWN_SUPPORT_FLAGS_EXPOSE_PIDS
|
||||
|
||||
#define FLATPAK_SPAWN_FLAGS_ALL (FLATPAK_SPAWN_FLAGS_CLEAR_ENV | \
|
||||
FLATPAK_SPAWN_FLAGS_LATEST_VERSION | \
|
||||
FLATPAK_SPAWN_FLAGS_SANDBOX | \
|
||||
FLATPAK_SPAWN_FLAGS_NO_NETWORK | \
|
||||
FLATPAK_SPAWN_FLAGS_WATCH_BUS | \
|
||||
FLATPAK_SPAWN_FLAGS_EXPOSE_PIDS | \
|
||||
FLATPAK_SPAWN_FLAGS_NOTIFY_START)
|
||||
FLATPAK_SPAWN_FLAGS_NOTIFY_START | \
|
||||
FLATPAK_SPAWN_FLAGS_SHARE_PIDS)
|
||||
|
||||
#define FLATPAK_SPAWN_SANDBOX_FLAGS_ALL (FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_DISPLAY | \
|
||||
FLATPAK_SPAWN_SANDBOX_FLAGS_SHARE_SOUND | \
|
||||
|
||||
Reference in New Issue
Block a user