From 44e3097dff3d25f4aaae5adeaca773232a16691d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 4 Dec 2023 18:23:31 +0100 Subject: [PATCH] dissect-image: make dissected_image_acquire_metadata() operate within a userns if possible 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 | 2 +- src/shared/discover-image.c | 5 ++++- src/shared/dissect-image.c | 18 +++++++++++++++--- src/shared/dissect-image.h | 2 +- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c index e4cc5360921..d6939152e04 100644 --- a/src/dissect/dissect.c +++ b/src/dissect/dissect.c @@ -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) diff --git a/src/shared/discover-image.c b/src/shared/discover-image.c index 564c7e05c0a..b7a97f2b63a 100644 --- a/src/shared/discover-image.c +++ b/src/shared/discover-image.c @@ -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; diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index ebaff0df123..a46891bffa4 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -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, diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h index d1f5b2c5802..7623c1181e7 100644 --- a/src/shared/dissect-image.h +++ b/src/shared/dissect-image.h @@ -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); -- 2.47.3