From 01359b7c00f1faa5e729e8abb3089a53b47c87ce Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
Date: Thu, 1 Aug 2019 14:54:37 +0100
Subject: [PATCH] wrap: Use readlink -f to canonicalize ld.so in the container

This fixes our ability to work with non-"merged /usr" sysroots, but
for now only if they have both i386 and x86_64 libc installed.

Signed-off-by: Simon McVittie <smcv@collabora.com>
---
 README.md  | 13 ++++++------
 src/wrap.c | 58 +++++++++++-------------------------------------------
 2 files changed, 18 insertions(+), 53 deletions(-)

diff --git a/README.md b/README.md
index cd0052942..643f243dd 100644
--- a/README.md
+++ b/README.md
@@ -244,19 +244,18 @@ Instructions for testing
 
     Or if you have a `chroot` environment with extra packages installed,
     such as the `/var/chroots/steamrt_scout_amd64` generated by
-    [`setup_chroot.sh`][], you can use that by making `files` a symbolic
-    link to it:
+    [`setup_chroot.sh`][] or an unpacked copy of
+    `com.valvesoftware.SteamRuntime.Sdk-amd64,i386-scout-sysroot.tar.gz`,
+    you can use that by making `files` a symbolic link to it:
 
         $ rm -fr ~/.steam/root/common/SteamLinuxRuntime/scout-chroot
         $ mkdir -p ~/.steam/root/common/SteamLinuxRuntime/scout-chroot
         $ ln -s /var/chroots/steamrt_scout_amd64 \
             ~/.steam/root/common/SteamLinuxRuntime/scout-chroot/files
 
-    (TODO: This is currently broken for chroots that are not merged-/usr.
-    so you will need to unpack
-    `com.valvesoftware.SteamRuntime.Sdk-amd64,i386-scout-sysroot.tar.gz`
-    into `/var/chroots/steamrt_scout_amd64` instead of using
-    [`setup_chroot.sh`][].)
+    Note that to use a `chroot` in this way, it must have at least
+    `libc6:amd64` and `libc6:i386` installed. `pressure-vessel` does not
+    currently support containers that do not have both word-sizes.
 
 * Launch a game once without pressure-vessel
 
diff --git a/src/wrap.c b/src/wrap.c
index 6c1e9dbb3..d26ab979e 100644
--- a/src/wrap.c
+++ b/src/wrap.c
@@ -911,7 +911,6 @@ bind_runtime (FlatpakBwrap *bwrap,
   gsize i, j;
   const gchar *member;
   g_autoptr(GString) dri_path = g_string_new ("");
-  gboolean runtime_is_usr = FALSE;
 
   g_return_val_if_fail (tools_dir != NULL, FALSE);
   g_return_val_if_fail (runtime != NULL, FALSE);
@@ -921,12 +920,6 @@ bind_runtime (FlatpakBwrap *bwrap,
 
   usr = g_build_filename (runtime, "usr", NULL);
 
-  if (!g_file_test (usr, G_FILE_TEST_IS_DIR))
-    {
-      /* runtime is assumed to be a merged /usr */
-      runtime_is_usr = TRUE;
-    }
-
   if (!bind_usr (bwrap, runtime, "/", error))
     return FALSE;
 
@@ -1148,10 +1141,15 @@ bind_runtime (FlatpakBwrap *bwrap,
               g_clear_pointer (&temp_bwrap, flatpak_bwrap_free);
 
               temp_bwrap = flatpak_bwrap_new (NULL);
-              flatpak_bwrap_append_bwrap (temp_bwrap, run_in_container);
               flatpak_bwrap_add_args (temp_bwrap,
-                                      tool_path,
-                                      "--resolve-ld.so", scratch,
+                                      bwrap->argv->pdata[0],
+                                      NULL);
+
+              if (!bind_usr (temp_bwrap, runtime, "/", error))
+                return FALSE;
+
+              flatpak_bwrap_add_args (temp_bwrap,
+                                      "readlink", "-f", ld_so,
                                       NULL);
               flatpak_bwrap_finish (temp_bwrap);
 
@@ -1162,42 +1160,10 @@ bind_runtime (FlatpakBwrap *bwrap,
                 return FALSE;
 
               g_debug ("Container path: %s -> %s", ld_so, real_path_in_runtime);
-
-              if (runtime_is_usr)
-                {
-                  g_debug ("Runtime is just /usr anyway");
-                  g_debug ("Mounting %s on %s", real_path_in_host, real_path_in_runtime);
-                  flatpak_bwrap_add_args (bwrap,
-                                          "--ro-bind", real_path_in_host,
-                                          real_path_in_runtime,
-                                          NULL);
-                }
-              else if (g_str_has_prefix (real_path_in_runtime, "/usr/"))
-                {
-                  g_debug ("Path in runtime starts with /usr already");
-                  g_debug ("Mounting %s on %s", real_path_in_host, real_path_in_runtime);
-                  flatpak_bwrap_add_args (bwrap,
-                                          "--ro-bind", real_path_in_host,
-                                          real_path_in_runtime,
-                                          NULL);
-                }
-              else
-                {
-                  /* We assume that /lib, /lib64 are just going to be
-                   * symlinks anyway.
-                   *
-                   * TODO: Support for non-merged-/usr runtimes? */
-                  g_autofree gchar *usr_path_in_runtime = NULL;
-
-                  g_debug ("Assuming runtime is merged-/usr");
-                  usr_path_in_runtime = g_build_filename ("/usr",
-                                                          real_path_in_runtime,
-                                                          NULL);
-                  flatpak_bwrap_add_args (bwrap,
-                                          "--ro-bind", real_path_in_host,
-                                          usr_path_in_runtime,
-                                          NULL);
-                }
+              flatpak_bwrap_add_args (bwrap,
+                                      "--ro-bind", real_path_in_host,
+                                      real_path_in_runtime,
+                                      NULL);
 
               g_debug ("Making host locale data visible in container");
 
-- 
GitLab