dissect-image: make dissected_image_acquire_metadata() operate within a userns if...
authorLennart Poettering <lennart@poettering.net>
Mon, 4 Dec 2023 17:23:31 +0000 (18:23 +0100)
committerLennart Poettering <lennart@poettering.net>
Sat, 6 Apr 2024 14:08:23 +0000 (16:08 +0200)
This opens the door for making the call work without privileges: if we
pass in a userns fd and DissectedImage that has mount fds then we can
acquire all information without privs.

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

index e4cc53609219a54fa276d04e2ac5b1c63329d2a8..d6939152e042ae29661190f8413dd7aaae914b7b 100644 (file)
@@ -875,7 +875,7 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
                 fflush(stdout);
         }
 
-        r = dissected_image_acquire_metadata(m, 0);
+        r = dissected_image_acquire_metadata(m, /* userns_fd= */ -EBADF, /* extra_flags= */ 0);
         if (r == -ENXIO)
                 return log_error_errno(r, "No root partition discovered.");
         if (r == -EUCLEAN)
index 564c7e05c0a7c07d12db81f76d3cb34ed8e59d78..b7a97f2b63aa475e20d3b7cae2d5b69ae45772bb 100644 (file)
@@ -1522,7 +1522,10 @@ int image_read_metadata(Image *i, const ImagePolicy *image_policy) {
                 if (r < 0)
                         return r;
 
-                r = dissected_image_acquire_metadata(m, flags);
+                r = dissected_image_acquire_metadata(
+                                m,
+                                /* userns_fd= */ -EBADF,
+                                flags);
                 if (r < 0)
                         return r;
 
index ebaff0df123f32e9977816ebcd665700b7767229..a46891bffa4366f27668708b61754ad257e7f99e 100644 (file)
@@ -3400,7 +3400,10 @@ int dissected_image_load_verity_sig_partition(
         return 1;
 }
 
-int dissected_image_acquire_metadata(DissectedImage *m, DissectImageFlags extra_flags) {
+int dissected_image_acquire_metadata(
+                DissectedImage *m,
+                int userns_fd,
+                DissectImageFlags extra_flags) {
 
         enum {
                 META_HOSTNAME,
@@ -3459,13 +3462,22 @@ int dissected_image_acquire_metadata(DissectedImage *m, DissectImageFlags extra_
                 goto finish;
         }
 
-        r = safe_fork("(sd-dissect)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, &child);
+        r = safe_fork("(sd-dissect)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM, &child);
         if (r < 0)
                 goto finish;
         if (r == 0) {
-                /* Child in a new mount namespace */
+                /* Child */
                 error_pipe[0] = safe_close(error_pipe[0]);
 
+                if (userns_fd < 0)
+                        r = detach_mount_namespace_harder(0, 0);
+                else
+                        r = detach_mount_namespace_userns(userns_fd);
+                if (r < 0) {
+                        log_debug_errno(r, "Failed to detach mount namespace: %m");
+                        goto inner_fail;
+                }
+
                 r = dissected_image_mount(
                                 m,
                                 t,
index d1f5b2c5802f8cf71aa813322fa2a8738868a4ea..7623c1181e78fed805d9324d79f4a918b0456aed 100644 (file)
@@ -172,7 +172,7 @@ int dissected_image_decrypt_interactively(DissectedImage *m, const char *passphr
 int dissected_image_mount(DissectedImage *m, const char *dest, uid_t uid_shift, uid_t uid_range, int userns_fd, DissectImageFlags flags);
 int dissected_image_mount_and_warn(DissectedImage *m, const char *where, uid_t uid_shift, uid_t uid_range, int userns_fd, DissectImageFlags flags);
 
-int dissected_image_acquire_metadata(DissectedImage *m, DissectImageFlags extra_flags);
+int dissected_image_acquire_metadata(DissectedImage *m, int userns_fd, DissectImageFlags extra_flags);
 
 Architecture dissected_image_architecture(DissectedImage *m);