composefs: Use lowerdir in /run
authorColin Walters <walters@verbum.org>
Sat, 22 Jul 2023 19:31:52 +0000 (15:31 -0400)
committerColin Walters <walters@verbum.org>
Sat, 22 Jul 2023 20:46:17 +0000 (16:46 -0400)
I just noticed that this was another constant string duplicated
between prepare-root.c and libostree-1.so, and I went to make
it a common `#define` in libotcore.la.

But then I thought "it's ugly to have this directory mixed into
the deployment namespace" because in some theoretical world
it could also be in the ostree commit, which would cause weird
behavior.

I think this is transient state that is better in `/run`, so move
it there.

src/libostree/ostree-sysroot-deploy.c
src/libotcore/otcore.h
src/switchroot/ostree-prepare-root.c
tests/inst/src/composefs.rs

index 5628f268e2f7984465819ed3bfb3242070ae09c6..0f55f07bc9a7c185c1282591e6082364d9ecd3f3 100644 (file)
@@ -696,13 +696,6 @@ checkout_deployment_tree (OstreeSysroot *sysroot, OstreeRepo *repo, OstreeDeploy
       if (!glnx_link_tmpfile_at (&tmpf, GLNX_LINK_TMPFILE_REPLACE, osdeploy_dfd, composefs_cfs_path,
                                  error))
         return FALSE;
-
-      /* This is where the erofs image will be temporarily mounted */
-      g_autofree char *composefs_mnt_path
-          = g_strdup_printf ("%s/.ostree.mnt", checkout_target_name);
-
-      if (!glnx_shutil_mkdir_p_at (osdeploy_dfd, composefs_mnt_path, 0775, cancellable, error))
-        return FALSE;
     }
 #endif
 
index 1b2973e5afdf599454cc53234151add1d5d79d36..a5bdb8f9f1c436c2563d2a5bd30e7ddb232e8893 100644 (file)
@@ -43,8 +43,19 @@ bool otcore_ed25519_init (void);
 gboolean otcore_validate_ed25519_signature (GBytes *data, GBytes *pubkey, GBytes *signature,
                                             bool *out_valid, GError **error);
 
+// Our directory with transient state (eventually /run/ostree-booted should be a link to
+// /run/ostree/booted)
+#define OTCORE_RUN_OSTREE "/run/ostree"
+// This sub-directory is transient state that should not be visible to other processes in general;
+// we make it with mode 0 (which requires CAP_DAC_OVERRIDE to pass through).
+#define OTCORE_RUN_OSTREE_PRIVATE "/run/ostree/.private"
+
 // The name of the composefs metadata root
 #define OSTREE_COMPOSEFS_NAME ".ostree.cfs"
+// The temporary directory used for the EROFS mount; it's in the .private directory
+// to help ensure that at least unprivileged code can't transiently see the underlying
+// EROFS mount if we somehow leaked it (but it *should* be unmounted always).
+#define OSTREE_COMPOSEFS_LOWERMNT OTCORE_RUN_OSTREE_PRIVATE "/cfsroot-lower"
 
 // The file written in the initramfs which contains an a{sv} of metadata
 // from ostree-prepare-root.
index 0f84ed1c3b15d18e886d9f366d0ce55503a5d120..5f35fc4345236eb40cde8f3dbaf535700b12f09b 100644 (file)
@@ -312,6 +312,11 @@ main (int argc, char *argv[])
     err (EXIT_FAILURE, "realpath(\"%s\")", root_arg);
   char *deploy_path = resolve_deploy_path (root_mountpoint);
 
+  if (mkdirat (AT_FDCWD, OTCORE_RUN_OSTREE, 0755) < 0)
+    err (EXIT_FAILURE, "Failed to create %s", OTCORE_RUN_OSTREE);
+  if (mkdirat (AT_FDCWD, OTCORE_RUN_OSTREE_PRIVATE, 0) < 0)
+    err (EXIT_FAILURE, "Failed to create %s", OTCORE_RUN_OSTREE_PRIVATE);
+
   /* Query the repository configuration - this is an operating system builder
    * choice.  More info: https://github.com/ostreedev/ostree/pull/1767
    */
@@ -406,10 +411,9 @@ main (int argc, char *argv[])
         }
 
       cfs_options.flags = LCFS_MOUNT_FLAGS_READONLY;
-
-      if (snprintf (srcpath, sizeof (srcpath), "%s/.ostree.mnt", deploy_path) < 0)
-        err (EXIT_FAILURE, "failed to assemble /boot/loader path");
-      cfs_options.image_mountdir = srcpath;
+      cfs_options.image_mountdir = OSTREE_COMPOSEFS_LOWERMNT;
+      if (mkdirat (AT_FDCWD, OSTREE_COMPOSEFS_LOWERMNT, 0700) < 0)
+        err (EXIT_FAILURE, "Failed to create %s", OSTREE_COMPOSEFS_LOWERMNT);
 
       if (expected_digest != NULL)
         {
index 3a737a3ca0e6583a8d276659319fd3e325f8137c..caa00c0cac4f1e09722f1083f66f8b255f362575 100644 (file)
@@ -1,3 +1,6 @@
+use std::os::unix::fs::MetadataExt;
+use std::path::Path;
+
 use anyhow::Result;
 use ostree_ext::glib;
 use xshell::cmd;
@@ -34,5 +37,14 @@ pub(crate) fn itest_composefs() -> Result<()> {
 
     assert_eq!(metadata.lookup::<bool>("composefs").unwrap(), Some(true));
 
+    let private_dir = Path::new("/run/ostree/.private");
+    assert_eq!(
+        std::fs::symlink_metadata(private_dir)?.mode() & !libc::S_IFMT,
+        0
+    );
+    assert!(std::fs::read_dir(private_dir.join("cfsroot-lower"))?
+        .next()
+        .is_none());
+
     Ok(())
 }