summaryrefslogtreecommitdiffstats
path: root/src/shared/dissect-image.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2021-04-28 17:23:29 +0200
committerLennart Poettering <lennart@poettering.net>2021-05-07 22:44:05 +0200
commit21b61b1dd26d4c4a4736aabac128037b67440e2a (patch)
tree87b1eaf878e3c4712fae8ddf6017b374a794b2d9 /src/shared/dissect-image.c
parentmount-util: add a helper that can add an idmap to an existing mount (diff)
downloadsystemd-21b61b1dd26d4c4a4736aabac128037b67440e2a.tar.xz
systemd-21b61b1dd26d4c4a4736aabac128037b67440e2a.zip
dissect-image: add support for optionally mounting images with idmapping on
Diffstat (limited to 'src/shared/dissect-image.c')
-rw-r--r--src/shared/dissect-image.c66
1 files changed, 45 insertions, 21 deletions
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");