diff options
Diffstat (limited to '')
-rw-r--r-- | src/shared/mount-util.c | 60 | ||||
-rw-r--r-- | src/shared/mount-util.h | 2 |
2 files changed, 52 insertions, 10 deletions
diff --git a/src/shared/mount-util.c b/src/shared/mount-util.c index 9d0d7c73df..4df391949b 100644 --- a/src/shared/mount-util.c +++ b/src/shared/mount-util.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include <errno.h> +#include <linux/loop.h> #include <stdlib.h> #include <sys/mount.h> #include <sys/stat.h> @@ -8,6 +9,7 @@ #include <unistd.h> #include "alloc-util.h" +#include "dissect-image.h" #include "extract-word.h" #include "fd-util.h" #include "fileio.h" @@ -27,6 +29,7 @@ #include "string-util.h" #include "strv.h" #include "tmpfile-util.h" +#include "user-util.h" int mount_fd(const char *source, int target_fd, @@ -747,14 +750,16 @@ int mount_option_mangle( return 0; } -int bind_mount_in_namespace( +static int mount_in_namespace( pid_t target, const char *propagate_path, const char *incoming_path, const char *src, const char *dest, bool read_only, - bool make_file_or_directory) { + bool make_file_or_directory, + const MountOptions *options, + bool is_image) { _cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 }; _cleanup_close_ int self_mntns_fd = -1, mntns_fd = -1, root_fd = -1, pidns_fd = -1, chased_src_fd = -1; @@ -772,6 +777,7 @@ int bind_mount_in_namespace( assert(incoming_path); assert(src); assert(dest); + assert(!options || is_image); r = namespace_open(target, &pidns_fd, &mntns_fd, NULL, NULL, &root_fd); if (r < 0) @@ -836,7 +842,10 @@ int bind_mount_in_namespace( /* Second, we mount the source file or directory to a directory inside of our MS_SLAVE playground. */ mount_tmp = strjoina(mount_slave, "/mount"); - r = make_mount_point_inode_from_stat(&st, mount_tmp, 0700); + if (is_image) + r = mkdir_p(mount_tmp, 0700); + else + r = make_mount_point_inode_from_stat(&st, mount_tmp, 0700); if (r < 0) { log_debug_errno(r, "Failed to create temporary mount point %s: %m", mount_tmp); goto finish; @@ -844,7 +853,10 @@ int bind_mount_in_namespace( mount_tmp_created = true; - r = mount_follow_verbose(LOG_DEBUG, chased_src, mount_tmp, NULL, MS_BIND, NULL); + if (is_image) + r = verity_dissect_and_mount(chased_src, mount_tmp, options); + else + r = mount_follow_verbose(LOG_DEBUG, chased_src, mount_tmp, NULL, MS_BIND, NULL); if (r < 0) goto finish; @@ -861,7 +873,7 @@ int bind_mount_in_namespace( * right-away. */ mount_outside = strjoina(propagate_path, "/XXXXXX"); - if (S_ISDIR(st.st_mode)) + if (is_image || S_ISDIR(st.st_mode)) r = mkdtemp(mount_outside) ? 0 : -errno; else { r = mkostemp_safe(mount_outside); @@ -881,7 +893,7 @@ int bind_mount_in_namespace( mount_outside_mounted = true; mount_tmp_mounted = false; - if (S_ISDIR(st.st_mode)) + if (is_image || S_ISDIR(st.st_mode)) (void) rmdir(mount_tmp); else (void) unlink(mount_tmp); @@ -908,8 +920,11 @@ int bind_mount_in_namespace( errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]); if (make_file_or_directory) { - (void) mkdir_parents(dest, 0755); - (void) make_mount_point_inode_from_stat(&st, dest, 0700); + if (!is_image) { + (void) mkdir_parents(dest, 0755); + (void) make_mount_point_inode_from_stat(&st, dest, 0700); + } else + (void) mkdir_p(dest, 0755); } /* Fifth, move the mount to the right place inside */ @@ -946,7 +961,7 @@ finish: if (mount_outside_mounted) (void) umount_verbose(LOG_DEBUG, mount_outside, UMOUNT_NOFOLLOW); if (mount_outside_created) { - if (S_ISDIR(st.st_mode)) + if (is_image || S_ISDIR(st.st_mode)) (void) rmdir(mount_outside); else (void) unlink(mount_outside); @@ -955,7 +970,7 @@ finish: if (mount_tmp_mounted) (void) umount_verbose(LOG_DEBUG, mount_tmp, UMOUNT_NOFOLLOW); if (mount_tmp_created) { - if (S_ISDIR(st.st_mode)) + if (is_image || S_ISDIR(st.st_mode)) (void) rmdir(mount_tmp); else (void) unlink(mount_tmp); @@ -968,3 +983,28 @@ finish: return r; } + +int bind_mount_in_namespace( + pid_t target, + const char *propagate_path, + const char *incoming_path, + const char *src, + const char *dest, + bool read_only, + bool make_file_or_directory) { + + return mount_in_namespace(target, propagate_path, incoming_path, src, dest, read_only, make_file_or_directory, NULL, false); +} + +int mount_image_in_namespace( + pid_t target, + const char *propagate_path, + const char *incoming_path, + const char *src, + const char *dest, + bool read_only, + bool make_file_or_directory, + const MountOptions *options) { + + return mount_in_namespace(target, propagate_path, incoming_path, src, dest, read_only, make_file_or_directory, options, true); +} diff --git a/src/shared/mount-util.h b/src/shared/mount-util.h index fa36dd7875..849c37e85b 100644 --- a/src/shared/mount-util.h +++ b/src/shared/mount-util.h @@ -6,6 +6,7 @@ #include <unistd.h> #include "alloc-util.h" +#include "dissect-image.h" #include "errno-util.h" #include "macro.h" @@ -99,3 +100,4 @@ static inline char* umount_and_rmdir_and_free(char *p) { DEFINE_TRIVIAL_CLEANUP_FUNC(char*, umount_and_rmdir_and_free); int bind_mount_in_namespace(pid_t target, const char *propagate_path, const char *incoming_path, const char *src, const char *dest, bool read_only, bool make_file_or_directory); +int mount_image_in_namespace(pid_t target, const char *propagate_path, const char *incoming_path, const char *src, const char *dest, bool read_only, bool make_file_or_directory, const MountOptions *options); |