From 581a32f7a07df356bda4da6fd8ce5331cb83e33e Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
Date: Wed, 21 Apr 2021 18:07:16 +0100
Subject: [PATCH] pv-runtime: Delete libraries that are overridden by an alias

If we got libbz2.so.1.0 from the host, for which libbz2.so.1 is an
alias, we will also want to remove libbz2.so.1 from the container.

Signed-off-by: Simon McVittie <smcv@collabora.com>
---
 pressure-vessel/runtime.c | 58 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/pressure-vessel/runtime.c b/pressure-vessel/runtime.c
index b3e8eb506..6dbdd7cd8 100644
--- a/pressure-vessel/runtime.c
+++ b/pressure-vessel/runtime.c
@@ -2904,6 +2904,34 @@ pv_runtime_remove_overridden_libraries (PvRuntime *self,
                 }
             }
 
+          /* scope for alias_link */
+            {
+              g_autofree gchar *alias_link = NULL;
+              g_autofree gchar *alias_target = NULL;
+
+              /* If we're looking at /usr/lib/MULTIARCH/libcurl.so.3, and a
+               * symlink .../aliases/libcurl.so.3 exists and points to
+               * e.g. .../overrides/lib/$MULTIARCH/libcurl.so.4, then
+               * /usr/lib/MULTIARCH/libcurl.so.3 was overridden and should
+               * be deleted. However, if .../aliases/libcurl.so.3 points to
+               * e.g. /usr/lib/MULTIARCH/libcurl.so.4, then the container's
+               * library was not overridden and we should not delete it. */
+              alias_link = g_build_filename (arch->aliases_in_current_namespace,
+                                             dent->d_name, NULL);
+              alias_target = glnx_readlinkat_malloc (AT_FDCWD, alias_link,
+                                                     NULL, NULL);
+
+              if (alias_target != NULL
+                  && flatpak_has_path_prefix (alias_target,
+                                              self->overrides_in_container))
+                {
+                  g_hash_table_replace (delete[i],
+                                        g_strdup (dent->d_name),
+                                        g_steal_pointer (&alias_link));
+                  continue;
+                }
+            }
+
           target = glnx_readlinkat_malloc (iters[i].fd, dent->d_name,
                                            NULL, NULL);
 
@@ -2928,6 +2956,36 @@ pv_runtime_remove_overridden_libraries (PvRuntime *self,
                 }
             }
 
+          if (target != NULL)
+            {
+              g_autofree gchar *alias_link = NULL;
+              g_autofree gchar *alias_target = NULL;
+
+              /* If we're looking at /usr/lib/MULTIARCH/libcurl.so.3, which
+               * points to libcurl.so.4, and a
+               * symlink .../aliases/libcurl.so.3 exists and points to
+               * e.g. .../overrides/lib/$MULTIARCH/libcurl.so.4, then
+               * /usr/lib/MULTIARCH/libcurl.so.3 was overridden and should
+               * be deleted. However, if .../aliases/libcurl.so.3 points to
+               * e.g. /usr/lib/MULTIARCH/libcurl.so.4, then the container's
+               * library was not overridden and we should not delete it. */
+              alias_link = g_build_filename (arch->aliases_in_current_namespace,
+                                             glnx_basename (target),
+                                             NULL);
+              alias_target = glnx_readlinkat_malloc (AT_FDCWD, alias_link,
+                                                     NULL, NULL);
+
+              if (alias_target != NULL
+                  && flatpak_has_path_prefix (alias_target,
+                                              self->overrides_in_container))
+                {
+                  g_hash_table_replace (delete[i],
+                                        g_strdup (dent->d_name),
+                                        g_steal_pointer (&alias_link));
+                  continue;
+                }
+            }
+
           libfd = _srt_resolve_in_sysroot (self->mutable_sysroot_fd, path,
                                            SRT_RESOLVE_FLAGS_READABLE, NULL,
                                            &local_error);
-- 
GitLab