Skip to content
Snippets Groups Projects
Commit feb948ed authored by Simon McVittie's avatar Simon McVittie
Browse files

wrap: Add the ability to unshare the pid namespace

This improves isolation between the host system and the game, and can
be used in conjunction with bwrap's init/reaper process to make game
termination fully reliable (unlike subreapers, killing the init process
automatically kills the entire pid namespace).

One major down-side of doing this is that if the game uses
process-ID-oriented APIs, for example older versions of
<https://github.com/FeralInteractive/gamemode

>, then they will not
work, because the process ID inside the container is not the same as
the process ID outside the container.

Unfortunately, Steam's own tracking of the processes that belong to a game
is one of the process-ID-oriented APIs that this harms, so this branch
does not unshare the pid namespace by default, only when requested. We
can use this to test whether it can be done without breaking Steam;
We will probably need to cope with separate pid namespaces if we create
new containers from inside a Flatpak environment.

Also add an option to unload the gameoverlayrenderer.so module, which
is not acceptable for production use, but at least works around this
well enough to unblock further testing.

Signed-off-by: default avatarSimon McVittie <smcv@collabora.com>
parent c41ad3c9
No related branches found
No related tags found
No related merge requests found
...@@ -211,6 +211,48 @@ class Gui: ...@@ -211,6 +211,48 @@ class Gui:
self.grid.attach(label, 1, row, 1, 1) self.grid.attach(label, 1, row, 1, 1)
row += 1 row += 1
self.unshare_pid_check = Gtk.CheckButton.new_with_label(
'Create a new process ID namespace'
)
share_pid = boolean_environment('PRESSURE_VESSEL_SHARE_PID', True)
self.unshare_pid_check.set_active(not share_pid)
self.grid.attach(self.unshare_pid_check, 1, row, 1, 1)
row += 1
label = Gtk.Label.new('')
label.set_markup(
'<small><i>'
"Creating a new process ID namespace is very experimental, "
"and is known to break Steam's tracking of running games."
'</i></small>'
)
label.set_halign(Gtk.Align.START)
label.set_line_wrap(True)
self.grid.attach(label, 1, row, 1, 1)
row += 1
self.keep_game_overlay_check = Gtk.CheckButton.new_with_label(
'Allow Steam Overlay'
)
remove = boolean_environment(
'PRESSURE_VESSEL_REMOVE_GAME_OVERLAY', False
)
self.keep_game_overlay_check.set_active(not remove)
self.grid.attach(self.keep_game_overlay_check, 1, row, 1, 1)
row += 1
label = Gtk.Label.new('')
label.set_markup(
'<small><i>'
'Disabling this seems to work around some of the issues with '
'process ID namespaces, but will break various Steam features.'
'</i></small>'
)
label.set_halign(Gtk.Align.START)
label.set_line_wrap(True)
self.grid.attach(label, 1, row, 1, 1)
row += 1
self.xterm_check = Gtk.CheckButton.new_with_label('Run in an xterm') self.xterm_check = Gtk.CheckButton.new_with_label('Run in an xterm')
self.xterm_check.set_active(False) self.xterm_check.set_active(False)
self.grid.attach(self.xterm_check, 1, row, 1, 1) self.grid.attach(self.xterm_check, 1, row, 1, 1)
...@@ -420,6 +462,16 @@ class Gui: ...@@ -420,6 +462,16 @@ class Gui:
else: else:
argv.append('--share-home') argv.append('--share-home')
if self.unshare_pid_check.get_active():
argv.append('--unshare-pid')
else:
argv.append('--share-pid')
if self.keep_game_overlay_check.get_active():
argv.append('--keep-game-overlay')
else:
argv.append('--remove-game-overlay')
if self.xterm_check.get_active(): if self.xterm_check.get_active():
argv.append('--terminal=xterm') argv.append('--terminal=xterm')
else: else:
......
...@@ -323,11 +323,13 @@ static char *opt_steam_app_id = NULL; ...@@ -323,11 +323,13 @@ static char *opt_steam_app_id = NULL;
static char *opt_home = NULL; static char *opt_home = NULL;
static gboolean opt_host_fallback = FALSE; static gboolean opt_host_fallback = FALSE;
static gboolean opt_host_graphics = TRUE; static gboolean opt_host_graphics = TRUE;
static gboolean opt_remove_game_overlay = FALSE;
static PvShell opt_shell = PV_SHELL_NONE; static PvShell opt_shell = PV_SHELL_NONE;
static GPtrArray *opt_ld_preload = NULL; static GPtrArray *opt_ld_preload = NULL;
static char *opt_runtime_base = NULL; static char *opt_runtime_base = NULL;
static char *opt_runtime = NULL; static char *opt_runtime = NULL;
static Tristate opt_share_home = TRISTATE_MAYBE; static Tristate opt_share_home = TRISTATE_MAYBE;
static gboolean opt_share_pid = TRUE;
static gboolean opt_verbose = FALSE; static gboolean opt_verbose = FALSE;
static gboolean opt_version = FALSE; static gboolean opt_version = FALSE;
static gboolean opt_version_only = FALSE; static gboolean opt_version_only = FALSE;
...@@ -517,6 +519,16 @@ static GOptionEntry options[] = ...@@ -517,6 +519,16 @@ static GOptionEntry options[] =
G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, &opt_host_ld_preload_cb, G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, &opt_host_ld_preload_cb,
"Add MODULE from the host system to LD_PRELOAD when executing COMMAND.", "Add MODULE from the host system to LD_PRELOAD when executing COMMAND.",
"MODULE" }, "MODULE" },
{ "remove-game-overlay", '\0',
G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_remove_game_overlay,
"Disable the Steam Overlay. "
"[Default if $PRESSURE_VESSEL_REMOVE_GAME_OVERLAY is 1]",
NULL },
{ "keep-game-overlay", '\0',
G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_remove_game_overlay,
"Do not disable the Steam Overlay. "
"[Default unless $PRESSURE_VESSEL_REMOVE_GAME_OVERLAY is 1]",
NULL },
{ "runtime", '\0', { "runtime", '\0',
G_OPTION_FLAG_NONE, G_OPTION_ARG_FILENAME, &opt_runtime, G_OPTION_FLAG_NONE, G_OPTION_ARG_FILENAME, &opt_runtime,
"Mount the given sysroot or merged /usr in the container, and augment " "Mount the given sysroot or merged /usr in the container, and augment "
...@@ -541,6 +553,16 @@ static GOptionEntry options[] = ...@@ -541,6 +553,16 @@ static GOptionEntry options[] =
"[Default if $PRESSURE_VESSEL_HOME is set or " "[Default if $PRESSURE_VESSEL_HOME is set or "
"$PRESSURE_VESSEL_SHARE_HOME is 0]", "$PRESSURE_VESSEL_SHARE_HOME is 0]",
NULL }, NULL },
{ "share-pid", '\0',
G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_share_pid,
"Do not create a new process ID namespace for the app. "
"[Default, unless $PRESSURE_VESSEL_SHARE_PID is 0]",
NULL },
{ "unshare-pid", '\0',
G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_share_pid,
"Create a new process ID namespace for the app. "
"[Default if $PRESSURE_VESSEL_SHARE_PID is 0]",
NULL },
{ "shell", '\0', { "shell", '\0',
G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, opt_shell_cb, G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, opt_shell_cb,
"--shell=after is equivalent to --shell-after, and so on. " "--shell=after is equivalent to --shell-after, and so on. "
...@@ -700,9 +722,12 @@ main (int argc, ...@@ -700,9 +722,12 @@ main (int argc,
if (opt_home != NULL && opt_home[0] == '\0') if (opt_home != NULL && opt_home[0] == '\0')
g_clear_pointer (&opt_home, g_free); g_clear_pointer (&opt_home, g_free);
opt_remove_game_overlay = boolean_environment ("PRESSURE_VESSEL_REMOVE_GAME_OVERLAY",
FALSE);
opt_share_home = tristate_environment ("PRESSURE_VESSEL_SHARE_HOME"); opt_share_home = tristate_environment ("PRESSURE_VESSEL_SHARE_HOME");
opt_host_graphics = boolean_environment ("PRESSURE_VESSEL_HOST_GRAPHICS", opt_host_graphics = boolean_environment ("PRESSURE_VESSEL_HOST_GRAPHICS",
TRUE); TRUE);
opt_share_pid = boolean_environment ("PRESSURE_VESSEL_SHARE_PID", TRUE);
opt_verbose = boolean_environment ("PRESSURE_VESSEL_VERBOSE", FALSE); opt_verbose = boolean_environment ("PRESSURE_VESSEL_VERBOSE", FALSE);
if (!opt_shell_cb ("$PRESSURE_VESSEL_SHELL", if (!opt_shell_cb ("$PRESSURE_VESSEL_SHELL",
...@@ -1078,6 +1103,13 @@ main (int argc, ...@@ -1078,6 +1103,13 @@ main (int argc,
goto out; goto out;
} }
if (!opt_share_pid)
{
g_warning ("Unsharing process ID namespace. This is not expected "
"to work...");
flatpak_bwrap_add_arg (bwrap, "--unshare-pid");
}
g_debug ("Adjusting LD_PRELOAD..."); g_debug ("Adjusting LD_PRELOAD...");
/* We need the LD_PRELOADs from Steam visible at the paths that were /* We need the LD_PRELOADs from Steam visible at the paths that were
...@@ -1102,6 +1134,13 @@ main (int argc, ...@@ -1102,6 +1134,13 @@ main (int argc,
if (g_file_test (preload, G_FILE_TEST_EXISTS)) if (g_file_test (preload, G_FILE_TEST_EXISTS))
{ {
if (opt_remove_game_overlay
&& g_str_has_suffix (preload, "/gameoverlayrenderer.so"))
{
g_debug ("Disabling Steam Overlay: %s", preload);
continue;
}
if (runtime != NULL if (runtime != NULL
&& (g_str_has_prefix (preload, "/usr/") && (g_str_has_prefix (preload, "/usr/")
|| g_str_has_prefix (preload, "/lib"))) || g_str_has_prefix (preload, "/lib")))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment