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

wrap: Tell child process to take out its own lock if necessary


Non-OFD locks don't propagate across fork(), and bwrap needs to clone()
itself (which behaves like fork() in this respect) to separate itself
into a parent outside the container and a child inside the container.

This change adds a weak dependency on Linux 3.15. If we run on an older
version, everything should still *work*, but there will be a short
period of time during which we have already decided to use the runtime,
but it is not locked (and in particular not protected from deletion).

Fixes: 959fd338 "wrap: Take out a lock on the container's runtime for the duration"
Signed-off-by: default avatarSimon McVittie <smcv@collabora.com>
parent 4ad7b057
Branches
Tags
No related merge requests found
...@@ -226,7 +226,8 @@ pv_bwrap_bind_usr (FlatpakBwrap *bwrap, ...@@ -226,7 +226,8 @@ pv_bwrap_bind_usr (FlatpakBwrap *bwrap,
{ {
if (g_str_has_prefix (member, "lib") if (g_str_has_prefix (member, "lib")
|| g_str_equal (member, "bin") || g_str_equal (member, "bin")
|| g_str_equal (member, "sbin")) || g_str_equal (member, "sbin")
|| g_str_equal (member, ".ref"))
{ {
dest = g_build_filename (mount_point, member, NULL); dest = g_build_filename (mount_point, member, NULL);
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Contains code taken from Flatpak. * Contains code taken from Flatpak.
* *
* Copyright © 2014-2019 Red Hat, Inc * Copyright © 2014-2019 Red Hat, Inc
* Copyright © 2017-2019 Collabora Ltd. * Copyright © 2017-2020 Collabora Ltd.
* *
* SPDX-License-Identifier: LGPL-2.1-or-later * SPDX-License-Identifier: LGPL-2.1-or-later
* *
...@@ -2568,15 +2568,46 @@ main (int argc, ...@@ -2568,15 +2568,46 @@ main (int argc,
* can't do that without breaking gameoverlayrender.so's assumptions. */ * can't do that without breaking gameoverlayrender.so's assumptions. */
if (runtime_lock != NULL) if (runtime_lock != NULL)
{ {
g_autofree gchar *fd_str = NULL;
int fd = pv_bwrap_lock_steal_fd (runtime_lock);
fd_str = g_strdup_printf ("%d", fd);
flatpak_bwrap_add_fd (bwrap, fd);
flatpak_bwrap_add_args (bwrap, flatpak_bwrap_add_args (bwrap,
"/run/pressure-vessel/bin/pressure-vessel-with-lock", "/run/pressure-vessel/bin/pressure-vessel-with-lock",
"--subreaper", "--subreaper",
"--fd", fd_str, NULL);
if (pv_bwrap_lock_is_ofd (runtime_lock))
{
int fd = pv_bwrap_lock_steal_fd (runtime_lock);
g_autofree gchar *fd_str = NULL;
g_debug ("Passing lock fd %d down to with-lock", fd);
flatpak_bwrap_add_fd (bwrap, fd);
fd_str = g_strdup_printf ("%d", fd);
flatpak_bwrap_add_args (bwrap,
"--fd", fd_str,
NULL);
}
else
{
/*
* We were unable to take out an open file descriptor lock,
* so it will be released on fork(). Tell the with-lock process
* to take out its own compatible lock instead. There will be
* a short window during which we have lost our lock but the
* with-lock process has not taken its lock - that's unavoidable
* if we want to use exec() to replace ourselves with the
* container.
*
* pv_bwrap_bind_usr() arranges for /.ref to either be a
* symbolic link to /usr/.ref which is the runtime_lock
* (if opt_runtime is a merged /usr), or the runtime_lock
* itself (otherwise).
*/
g_debug ("Telling process in container to lock /.ref");
flatpak_bwrap_add_args (bwrap,
"--lock-file", "/.ref",
NULL);
}
flatpak_bwrap_add_args (bwrap,
"--", "--",
NULL); NULL);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment