From 12e3dc051fe9f48deac9e9626746ca2d31cd66d9 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 31 Jul 2020 15:13:33 +0100 Subject: [PATCH] exports: Try harder to export usrmerge symlinks as symlinks In applications with --filesystem=host or --filesystem=host-os, the library directories in /run/host/usr and /run/host/lib* can be used like a sysroot to inspect the host's library stack, regardless of whether the host system has undergone the "/usr merge" or not. This is particularly relevant for Steam's pressure-vessel container tool, which imports graphics drivers from the host system, or for potential future work on using host graphics drivers via libcapsule in Flatpak apps. The original implementation of this feature assumed that the /usr merge always creates symbolic links /foo -> /usr/foo or /foo -> usr/foo, for some value of foo. However, Arch Linux uses a variation of multilib in which /usr/lib contains 64-bit libraries, and has a non-matching symbolic link /lib64 -> usr/lib (instead of a chain of symlinks /lib64 -> usr/lib64 -> lib). Similarly, Arch uses /sbin -> usr/bin and /usr/sbin -> bin, instead of a chain of symlinks /sbin -> usr/sbin -> bin. This led to Flatpak ignoring the symlink and treating it like a directory, so the host /usr/lib would be bind-mounted on both /run/host/usr/lib and /run/host/lib64. This is *mostly* equivalent, but whether a directory is a symlink or a real directory sometimes matters, for example when evaluating relative symlinks that contain ".." components; so try harder to preserve symlinks as symlinks. Fixes: 08d65c54 "exports: If --filesystem=host, provide /run/host/lib etc." Signed-off-by: Simon McVittie --- common/flatpak-exports.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/common/flatpak-exports.c b/common/flatpak-exports.c index 912c5755..25894e71 100644 --- a/common/flatpak-exports.c +++ b/common/flatpak-exports.c @@ -325,18 +325,17 @@ flatpak_exports_append_bwrap_args (FlatpakExports *exports, target = glnx_readlinkat_malloc (-1, subdir, NULL, NULL); if (target != NULL && - g_str_has_prefix (target, "usr/") && - g_strcmp0 (target + 3, subdir) == 0) + g_str_has_prefix (target, "usr/")) { - /* e.g. /lib32 is a relative symlink to usr/lib32; + /* e.g. /lib32 is a relative symlink to usr/lib32, or + * on Arch Linux, /lib64 is a relative symlink to usr/lib; * keep it relative */ flatpak_bwrap_add_args (bwrap, "--symlink", target, run_host_subdir, NULL); } else if (target != NULL && - g_str_has_prefix (target, "/usr/") && - g_strcmp0 (target + 4, subdir) == 0) + g_str_has_prefix (target, "/usr/")) { /* e.g. /lib32 is an absolute symlink to /usr/lib32; make * it a relative symlink to usr/lib32 instead by skipping