]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dissect-image: introduce new get_common_dissect_directory() helper
authorLennart Poettering <lennart@poettering.net>
Mon, 4 Dec 2023 17:15:41 +0000 (18:15 +0100)
committerLuca Boccassi <luca.boccassi@gmail.com>
Thu, 18 Jan 2024 01:30:10 +0000 (01:30 +0000)
So far, if some component mounts a DDI in some local mount namespace we
created a temporary mountpoint in /tmp/ for that. Let's instead use the
same directory inode in /run/ instead. This is safe, since if everything
runs in a local mount namespace (with propagation on /run/ off) then
they shouldn't fight for the inode. And it relieves us from having to
clean up the directory after use. Morever, it allows us to run without
/tmp/ mounted.

This only moves dissect-image.c and the dissec tool over. More stuff is
moved over later.

src/dissect/dissect.c
src/shared/dissect-image.c
src/shared/dissect-image.h

index 2b080257fed7363fff77e02c8a3f12a19a17ad69..dce0209140bf5418040c46a6fa2491b309dfbb2d 100644 (file)
@@ -1273,8 +1273,7 @@ static int mtree_print_item(
 
 static int action_list_or_mtree_or_copy(DissectedImage *m, LoopDevice *d) {
         _cleanup_(umount_and_rmdir_and_freep) char *mounted_dir = NULL;
-        _cleanup_(rmdir_and_freep) char *created_dir = NULL;
-        _cleanup_free_ char *temp = NULL;
+        _cleanup_free_ char *t = NULL;
         const char *root;
         int r;
 
@@ -1288,19 +1287,13 @@ static int action_list_or_mtree_or_copy(DissectedImage *m, LoopDevice *d) {
                 if (r < 0)
                         return log_error_errno(r, "Failed to detach mount namespace: %m");
 
-                r = tempfn_random_child(NULL, program_invocation_short_name, &temp);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to generate temporary mount directory: %m");
-
-                r = mkdir_p(temp, 0700);
+                r = get_common_dissect_directory(&t);
                 if (r < 0)
-                        return log_error_errno(r, "Failed to create mount point: %m");
-
-                created_dir = TAKE_PTR(temp);
+                        return log_error_errno(r, "Failed generate private mount directory: %m");
 
                 r = dissected_image_mount_and_warn(
                                 m,
-                                created_dir,
+                                t,
                                 /* uid_shift= */ UID_INVALID,
                                 /* uid_range= */ UID_INVALID,
                                 /* userns_fd= */ -EBADF,
@@ -1308,7 +1301,7 @@ static int action_list_or_mtree_or_copy(DissectedImage *m, LoopDevice *d) {
                 if (r < 0)
                         return r;
 
-                mounted_dir = TAKE_PTR(created_dir);
+                mounted_dir = TAKE_PTR(t);
 
                 r = loop_device_flock(d, LOCK_UN);
                 if (r < 0)
index e5e47e4ac6d7480e74f27327eaf7753e580d077a..5b664d2333ef72d74150d572795bbfcd8a568678 100644 (file)
@@ -3382,11 +3382,10 @@ int dissected_image_acquire_metadata(DissectedImage *m, DissectImageFlags extra_
         };
 
         _cleanup_strv_free_ char **machine_info = NULL, **os_release = NULL, **initrd_release = NULL, **sysext_release = NULL, **confext_release = NULL;
+        _cleanup_free_ char *hostname = NULL, *t = NULL;
         _cleanup_close_pair_ int error_pipe[2] = EBADF_PAIR;
-        _cleanup_(rmdir_and_freep) char *t = NULL;
         _cleanup_(sigkill_waitp) pid_t child = 0;
         sd_id128_t machine_id = SD_ID128_NULL;
-        _cleanup_free_ char *hostname = NULL;
         unsigned n_meta_initialized = 0;
         int fds[2 * _META_MAX], r, v;
         int has_init_system = -1;
@@ -3405,7 +3404,7 @@ int dissected_image_acquire_metadata(DissectedImage *m, DissectImageFlags extra_
                 }
         }
 
-        r = mkdtemp_malloc("/tmp/dissect-XXXXXX", &t);
+        r = get_common_dissect_directory(&t);
         if (r < 0)
                 goto finish;
 
@@ -4070,3 +4069,29 @@ int verity_dissect_and_mount(
 
         return 0;
 }
+
+int get_common_dissect_directory(char **ret) {
+        _cleanup_free_ char *t = NULL;
+        int r;
+
+        /* A common location we mount dissected images to. The assumption is that everyone who uses this
+         * function runs in their own private mount namespace (with mount propagation off on /run/systemd/,
+         * and thus can mount something here without affecting anyone else). */
+
+        t = strdup("/run/systemd/dissect-root");
+        if (!t)
+                return log_oom_debug();
+
+        r = mkdir_parents(t, 0755);
+        if (r < 0)
+                return log_debug_errno(r, "Failed to create parent dirs of mount point '%s': %m", t);
+
+        r = RET_NERRNO(mkdir(t, 0000)); /* It's supposed to be overmounted, hence let's make this inaccessible */
+        if (r < 0 && r != -EEXIST)
+                return log_debug_errno(r, "Failed to create mount point '%s': %m", t);
+
+        if (ret)
+                *ret = TAKE_PTR(t);
+
+        return 0;
+}
index ed02049ed0c7190768a22c4e1a2cc3340f880658..2366a383979499df720d4de496ea9f2219f90a7d 100644 (file)
@@ -229,3 +229,5 @@ static inline const char *dissected_partition_fstype(const DissectedPartition *m
 
         return m->decrypted_node ? m->decrypted_fstype : m->fstype;
 }
+
+int get_common_dissect_directory(char **ret);