From 7bb056dc8500db1c300b6df0dd40578ae5ccef74 Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
Date: Fri, 19 Apr 2024 16:44:41 +0100
Subject: [PATCH] pv-wrap, FlatpakExports: Refuse to export parents of a
 reserved directory

Some of our reserved paths, notably /run/pressure-vessel and
/var/pressure-vessel, are not at the top level. We must avoid allowing
the parents of these directories to be exported, because if we allowed
that, it would break our ability to write to the child: for example, if
we bind-mount /run from the host, we will not be able to create
/run/pressure-vessel in the root-owned /run.

This is very similar to
https://github.com/flatpak/flatpak/commit/e3507918c0e496b0d111653e0e15e74108dbce16
in the Flatpak 1.15.x development branch, also written by me.

steamrt/tasks#434

Helps: https://github.com/ValveSoftware/steam-for-linux/issues/10789
Signed-off-by: Simon McVittie <smcv@collabora.com>
---
 pressure-vessel/flatpak-exports.c | 11 +++++++++++
 pressure-vessel/wrap-context.c    |  7 +++++++
 2 files changed, 18 insertions(+)

diff --git a/pressure-vessel/flatpak-exports.c b/pressure-vessel/flatpak-exports.c
index c3af3a1c5..eb1a05a1a 100644
--- a/pressure-vessel/flatpak-exports.c
+++ b/pressure-vessel/flatpak-exports.c
@@ -976,6 +976,17 @@ _exports_path_expose (FlatpakExports *exports,
           g_debug ("skipping export for path %s in unsupported prefix", path);
           return FALSE;
         }
+
+      /* Also don't expose directories that are a parent of a directory
+       * that is "owned" by the sandboxing framework. For example, because
+       * Flatpak controls /run/host and /run/flatpak, we cannot allow
+       * --filesystem=/run, which would prevent us from creating the
+       * contents of /run/host and /run/flatpak. */
+      if (flatpak_has_path_prefix (pv_reserved_paths[i], path))
+        {
+          g_debug ("skipping export for path %s above unsupported prefix", path);
+          return FALSE;
+        }
     }
 
   for (i = 0; flatpak_abs_usrmerged_dirs[i] != NULL; i++)
diff --git a/pressure-vessel/wrap-context.c b/pressure-vessel/wrap-context.c
index 112175829..e8c4222e4 100644
--- a/pressure-vessel/wrap-context.c
+++ b/pressure-vessel/wrap-context.c
@@ -1085,6 +1085,13 @@ pv_wrap_context_export_if_allowed (PvWrapContext *self,
                               source, before, after, flags);
           return FALSE;
         }
+
+      if (_srt_get_path_after (reserved_paths[i], path) != NULL)
+        {
+          export_not_allowed (self, path, reserved_paths[i],
+                              source, before, after, flags);
+          return FALSE;
+        }
     }
 
   if (g_strcmp0 (path, host_path) == 0)
-- 
GitLab