diff options
-rw-r--r-- | src/core/namespace.c | 2 | ||||
-rw-r--r-- | src/dissect/dissect.c | 4 | ||||
-rw-r--r-- | src/nspawn/nspawn.c | 2 | ||||
-rw-r--r-- | src/portable/portable.c | 2 | ||||
-rw-r--r-- | src/shared/dissect-image.c | 66 | ||||
-rw-r--r-- | src/shared/dissect-image.h | 5 | ||||
-rw-r--r-- | src/sysext/sysext.c | 1 | ||||
-rw-r--r-- | src/test/test-loop-block.c | 4 |
8 files changed, 57 insertions, 29 deletions
diff --git a/src/core/namespace.c b/src/core/namespace.c index acf8d14b67..6d77ce9967 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -2170,7 +2170,7 @@ int setup_namespace( if (root_image) { /* A root image is specified, mount it to the right place */ - r = dissected_image_mount(dissected_image, root, UID_INVALID, dissect_image_flags); + r = dissected_image_mount(dissected_image, root, UID_INVALID, UID_INVALID, dissect_image_flags); if (r < 0) { log_debug_errno(r, "Failed to mount root image: %m"); goto finish; diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c index ef11faaf42..47feba3d62 100644 --- a/src/dissect/dissect.c +++ b/src/dissect/dissect.c @@ -582,7 +582,7 @@ static int action_mount(DissectedImage *m, LoopDevice *d) { if (r < 0) return r; - r = dissected_image_mount_and_warn(m, arg_path, UID_INVALID, arg_flags); + r = dissected_image_mount_and_warn(m, arg_path, UID_INVALID, UID_INVALID, arg_flags); if (r < 0) return r; @@ -628,7 +628,7 @@ static int action_copy(DissectedImage *m, LoopDevice *d) { created_dir = TAKE_PTR(temp); - r = dissected_image_mount_and_warn(m, created_dir, UID_INVALID, arg_flags); + r = dissected_image_mount_and_warn(m, created_dir, UID_INVALID, UID_INVALID, arg_flags); if (r < 0) return r; diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index b5e5474231..d69b95598e 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -3605,6 +3605,7 @@ static int outer_child( dissected_image, directory, arg_uid_shift, + arg_uid_range, DISSECT_IMAGE_MOUNT_ROOT_ONLY| DISSECT_IMAGE_DISCARD_ON_LOOP| DISSECT_IMAGE_USR_NO_ROOT| @@ -3696,6 +3697,7 @@ static int outer_child( dissected_image, directory, arg_uid_shift, + arg_uid_range, DISSECT_IMAGE_MOUNT_NON_ROOT_ONLY| DISSECT_IMAGE_DISCARD_ON_LOOP| DISSECT_IMAGE_USR_NO_ROOT| diff --git a/src/portable/portable.c b/src/portable/portable.c index 53c4d8e25b..2eebdc08ae 100644 --- a/src/portable/portable.c +++ b/src/portable/portable.c @@ -426,7 +426,7 @@ static int portable_extract_by_path( if (r == 0) { seq[0] = safe_close(seq[0]); - r = dissected_image_mount(m, tmpdir, UID_INVALID, DISSECT_IMAGE_READ_ONLY); + r = dissected_image_mount(m, tmpdir, UID_INVALID, UID_INVALID, DISSECT_IMAGE_READ_ONLY); if (r < 0) { log_debug_errno(r, "Failed to mount dissected image: %m"); goto child_finish; diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 1f7ea3ec5b..3cf00adb6f 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -1472,11 +1472,12 @@ static int mount_partition( const char *where, const char *directory, uid_t uid_shift, + uid_t uid_range, DissectImageFlags flags) { _cleanup_free_ char *chased = NULL, *options = NULL; const char *p, *node, *fstype; - bool rw; + bool rw, remap_uid_gid = false; int r; assert(m); @@ -1536,14 +1537,18 @@ static int mount_partition( return -ENOMEM; } - if (uid_is_valid(uid_shift) && uid_shift != 0 && fstype_can_uid_gid(fstype)) { - _cleanup_free_ char *uid_option = NULL; + if (uid_is_valid(uid_shift) && uid_shift != 0) { - if (asprintf(&uid_option, "uid=" UID_FMT ",gid=" GID_FMT, uid_shift, (gid_t) uid_shift) < 0) - return -ENOMEM; + if (fstype_can_uid_gid(fstype)) { + _cleanup_free_ char *uid_option = NULL; - if (!strextend_with_separator(&options, ",", uid_option)) - return -ENOMEM; + if (asprintf(&uid_option, "uid=" UID_FMT ",gid=" GID_FMT, uid_shift, (gid_t) uid_shift) < 0) + return -ENOMEM; + + if (!strextend_with_separator(&options, ",", uid_option)) + return -ENOMEM; + } else if (FLAGS_SET(flags, DISSECT_IMAGE_MOUNT_IDMAPPED)) + remap_uid_gid = true; } if (!isempty(m->mount_options)) @@ -1578,6 +1583,12 @@ static int mount_partition( if (rw && m->growfs && FLAGS_SET(flags, DISSECT_IMAGE_GROWFS)) (void) fs_grow(node, p); + if (remap_uid_gid) { + r = remount_idmap(p, uid_shift, uid_range); + if (r < 0) + return r; + } + return 1; } @@ -1607,7 +1618,13 @@ static int mount_root_tmpfs(const char *where, uid_t uid_shift, DissectImageFlag return 1; } -int dissected_image_mount(DissectedImage *m, const char *where, uid_t uid_shift, DissectImageFlags flags) { +int dissected_image_mount( + DissectedImage *m, + const char *where, + uid_t uid_shift, + uid_t uid_range, + DissectImageFlags flags) { + int r, xbootldr_mounted; assert(m); @@ -1631,14 +1648,14 @@ int dissected_image_mount(DissectedImage *m, const char *where, uid_t uid_shift, /* First mount the root fs. If there's none we use a tmpfs. */ if (m->partitions[PARTITION_ROOT].found) - r = mount_partition(m->partitions + PARTITION_ROOT, where, NULL, uid_shift, flags); + r = mount_partition(m->partitions + PARTITION_ROOT, where, NULL, uid_shift, uid_range, flags); else r = mount_root_tmpfs(where, uid_shift, flags); if (r < 0) return r; /* For us mounting root always means mounting /usr as well */ - r = mount_partition(m->partitions + PARTITION_USR, where, "/usr", uid_shift, flags); + r = mount_partition(m->partitions + PARTITION_USR, where, "/usr", uid_shift, uid_range, flags); if (r < 0) return r; @@ -1659,23 +1676,23 @@ int dissected_image_mount(DissectedImage *m, const char *where, uid_t uid_shift, if (flags & DISSECT_IMAGE_MOUNT_ROOT_ONLY) return 0; - r = mount_partition(m->partitions + PARTITION_HOME, where, "/home", uid_shift, flags); + r = mount_partition(m->partitions + PARTITION_HOME, where, "/home", uid_shift, uid_range, flags); if (r < 0) return r; - r = mount_partition(m->partitions + PARTITION_SRV, where, "/srv", uid_shift, flags); + r = mount_partition(m->partitions + PARTITION_SRV, where, "/srv", uid_shift, uid_range, flags); if (r < 0) return r; - r = mount_partition(m->partitions + PARTITION_VAR, where, "/var", uid_shift, flags); + r = mount_partition(m->partitions + PARTITION_VAR, where, "/var", uid_shift, uid_range, flags); if (r < 0) return r; - r = mount_partition(m->partitions + PARTITION_TMP, where, "/var/tmp", uid_shift, flags); + r = mount_partition(m->partitions + PARTITION_TMP, where, "/var/tmp", uid_shift, uid_range, flags); if (r < 0) return r; - xbootldr_mounted = mount_partition(m->partitions + PARTITION_XBOOTLDR, where, "/boot", uid_shift, flags); + xbootldr_mounted = mount_partition(m->partitions + PARTITION_XBOOTLDR, where, "/boot", uid_shift, uid_range, flags); if (xbootldr_mounted < 0) return xbootldr_mounted; @@ -1701,7 +1718,7 @@ int dissected_image_mount(DissectedImage *m, const char *where, uid_t uid_shift, return r; } else if (dir_is_empty(p) > 0) { /* It exists and is an empty directory. Let's mount the ESP there. */ - r = mount_partition(m->partitions + PARTITION_ESP, where, "/boot", uid_shift, flags); + r = mount_partition(m->partitions + PARTITION_ESP, where, "/boot", uid_shift, uid_range, flags); if (r < 0) return r; @@ -1713,7 +1730,7 @@ int dissected_image_mount(DissectedImage *m, const char *where, uid_t uid_shift, if (!esp_done) { /* OK, let's mount the ESP now to /efi (possibly creating the dir if missing) */ - r = mount_partition(m->partitions + PARTITION_ESP, where, "/efi", uid_shift, flags); + r = mount_partition(m->partitions + PARTITION_ESP, where, "/efi", uid_shift, uid_range, flags); if (r < 0) return r; } @@ -1722,13 +1739,19 @@ int dissected_image_mount(DissectedImage *m, const char *where, uid_t uid_shift, return 0; } -int dissected_image_mount_and_warn(DissectedImage *m, const char *where, uid_t uid_shift, DissectImageFlags flags) { +int dissected_image_mount_and_warn( + DissectedImage *m, + const char *where, + uid_t uid_shift, + uid_t uid_range, + DissectImageFlags flags) { + int r; assert(m); assert(where); - r = dissected_image_mount(m, where, uid_shift, flags); + r = dissected_image_mount(m, where, uid_shift, uid_range, flags); if (r == -ENXIO) return log_error_errno(r, "Not root file system found in image."); if (r == -EMEDIUMTYPE) @@ -2523,6 +2546,7 @@ int dissected_image_acquire_metadata(DissectedImage *m) { m, t, UID_INVALID, + UID_INVALID, DISSECT_IMAGE_READ_ONLY| DISSECT_IMAGE_MOUNT_ROOT_ONLY| DISSECT_IMAGE_VALIDATE_OS| @@ -2811,7 +2835,7 @@ int mount_image_privately_interactively( created_dir = TAKE_PTR(temp); - r = dissected_image_mount_and_warn(dissected_image, created_dir, UID_INVALID, flags); + r = dissected_image_mount_and_warn(dissected_image, created_dir, UID_INVALID, UID_INVALID, flags); if (r < 0) return r; @@ -2917,7 +2941,7 @@ int verity_dissect_and_mount( if (r < 0) return log_debug_errno(r, "Failed to umount under destination directory %s: %m", dest); - r = dissected_image_mount(dissected_image, dest, UID_INVALID, dissect_image_flags); + r = dissected_image_mount(dissected_image, dest, UID_INVALID, UID_INVALID, dissect_image_flags); if (r < 0) return log_debug_errno(r, "Failed to mount image: %m"); diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h index b2f5c5dc96..c961ee3e71 100644 --- a/src/shared/dissect-image.h +++ b/src/shared/dissect-image.h @@ -112,6 +112,7 @@ typedef enum DissectImageFlags { DISSECT_IMAGE_READ_ONLY = DISSECT_IMAGE_DEVICE_READ_ONLY | DISSECT_IMAGE_MOUNT_READ_ONLY, DISSECT_IMAGE_GROWFS = 1 << 18, /* Grow file systems in partitions marked for that to the size of the partitions after mount */ + DISSECT_IMAGE_MOUNT_IDMAPPED = 1 << 19, /* Mount mounts with kernel 5.12-style userns ID mapping, if file sytem type doesn't support uid=/gid= */ } DissectImageFlags; struct DissectedImage { @@ -169,8 +170,8 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(DissectedImage*, dissected_image_unref); int dissected_image_decrypt(DissectedImage *m, const char *passphrase, const VeritySettings *verity, DissectImageFlags flags, DecryptedImage **ret); int dissected_image_decrypt_interactively(DissectedImage *m, const char *passphrase, const VeritySettings *verity, DissectImageFlags flags, DecryptedImage **ret); -int dissected_image_mount(DissectedImage *m, const char *dest, uid_t uid_shift, DissectImageFlags flags); -int dissected_image_mount_and_warn(DissectedImage *m, const char *where, uid_t uid_shift, DissectImageFlags flags); +int dissected_image_mount(DissectedImage *m, const char *dest, uid_t uid_shift, uid_t uid_range, DissectImageFlags flags); +int dissected_image_mount_and_warn(DissectedImage *m, const char *where, uid_t uid_shift, uid_t uid_range, DissectImageFlags flags); int dissected_image_acquire_metadata(DissectedImage *m); diff --git a/src/sysext/sysext.c b/src/sysext/sysext.c index 76a21afea6..572e4007fe 100644 --- a/src/sysext/sysext.c +++ b/src/sysext/sysext.c @@ -551,6 +551,7 @@ static int merge_subprocess(Hashmap *images, const char *workspace) { m, p, UID_INVALID, + UID_INVALID, flags); if (r < 0) return r; diff --git a/src/test/test-loop-block.c b/src/test/test-loop-block.c index ba44b5f3f9..57f3279b67 100644 --- a/src/test/test-loop-block.c +++ b/src/test/test-loop-block.c @@ -77,7 +77,7 @@ static void* thread_func(void *ptr) { assert_se(dissected->partitions[PARTITION_HOME].found); assert_se(dissected->partitions[PARTITION_HOME].node); - r = dissected_image_mount(dissected, mounted, UID_INVALID, DISSECT_IMAGE_READ_ONLY); + r = dissected_image_mount(dissected, mounted, UID_INVALID, UID_INVALID, DISSECT_IMAGE_READ_ONLY); log_notice_errno(r, "Mounted %s → %s: %m", loop->node, mounted); assert_se(r >= 0); @@ -217,7 +217,7 @@ int main(int argc, char *argv[]) { assert_se(mkdtemp_malloc(NULL, &mounted) >= 0); /* This first (writable) mount will initialize the mount point dirs, so that the subsequent read-only ones can work */ - assert_se(dissected_image_mount(dissected, mounted, UID_INVALID, 0) >= 0); + assert_se(dissected_image_mount(dissected, mounted, UID_INVALID, UID_INVALID, 0) >= 0); assert_se(umount_recursive(mounted, 0) >= 0); loop = loop_device_unref(loop); |