diff --git a/src/core/execute.c b/src/core/execute.c index 2cb2392d16..4e75d86472 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -2581,7 +2581,7 @@ static int apply_mount_namespace( needs_sandboxing ? context->protect_home : PROTECT_HOME_NO, needs_sandboxing ? context->protect_system : PROTECT_SYSTEM_NO, context->mount_flags, - DISSECT_IMAGE_DISCARD_ON_LOOP, + DISSECT_IMAGE_DISCARD_ON_LOOP|DISSECT_IMAGE_RELAX_VAR_CHECK, error_path); /* If we couldn't set up the namespace this is probably due to a missing capability. setup_namespace() reports diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c index c1be6c034c..2fef95aa02 100644 --- a/src/dissect/dissect.c +++ b/src/dissect/dissect.c @@ -22,7 +22,7 @@ static enum { } arg_action = ACTION_DISSECT; static const char *arg_image = NULL; static const char *arg_path = NULL; -static DissectImageFlags arg_flags = DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_DISCARD_ON_LOOP; +static DissectImageFlags arg_flags = DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_DISCARD_ON_LOOP|DISSECT_IMAGE_RELAX_VAR_CHECK; static void *arg_root_hash = NULL; static size_t arg_root_hash_size = 0; diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index 4aac903aa6..04691a62c4 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -697,6 +697,18 @@ static int enumerate_partitions(dev_t devnum) { r = k; } + if (m->partitions[PARTITION_VAR].found) { + k = add_partition_mount(m->partitions + PARTITION_VAR, "var", "/var", "Variable Data Partition"); + if (k < 0) + r = k; + } + + if (m->partitions[PARTITION_TMP].found) { + k = add_partition_mount(m->partitions + PARTITION_TMP, "var-tmp", "/var/tmp", "Temporary Data Partition"); + if (k < 0) + r = k; + } + if (m->partitions[PARTITION_ROOT].found) { k = add_root_rw(m->partitions + PARTITION_ROOT); if (k < 0) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 9113f6e323..962b2d0209 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -5058,7 +5058,7 @@ static int run(int argc, char *argv[]) { loop->fd, arg_image, arg_root_hash, arg_root_hash_size, - DISSECT_IMAGE_REQUIRE_ROOT, + DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_RELAX_VAR_CHECK, &dissected_image); if (r == -ENOPKG) { /* dissected_image_and_warn() already printed a brief error message. Extend on that with more details */ diff --git a/src/portable/portable.c b/src/portable/portable.c index 7a86398a4b..e18826ab26 100644 --- a/src/portable/portable.c +++ b/src/portable/portable.c @@ -387,7 +387,7 @@ static int portable_extract_by_path( if (r < 0) return log_debug_errno(r, "Failed to create temporary directory: %m"); - r = dissect_image(d->fd, NULL, 0, DISSECT_IMAGE_READ_ONLY|DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_DISCARD_ON_LOOP, &m); + r = dissect_image(d->fd, NULL, 0, DISSECT_IMAGE_READ_ONLY|DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_DISCARD_ON_LOOP|DISSECT_IMAGE_RELAX_VAR_CHECK, &m); if (r == -ENOPKG) sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Couldn't identify a suitable partition table or file system in '%s'.", path); else if (r == -EADDRNOTAVAIL) diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 11d21c3a4d..087c3dc345 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -598,6 +598,43 @@ int dissect_image( if (!generic_node) return -ENOMEM; } + + } else if (sd_id128_equal(type_id, GPT_TMP)) { + + if (pflags & GPT_FLAG_NO_AUTO) + continue; + + designator = PARTITION_TMP; + rw = !(pflags & GPT_FLAG_READ_ONLY); + + } else if (sd_id128_equal(type_id, GPT_VAR)) { + + if (pflags & GPT_FLAG_NO_AUTO) + continue; + + if (!FLAGS_SET(flags, DISSECT_IMAGE_RELAX_VAR_CHECK)) { + sd_id128_t var_uuid; + + /* For /var we insist that the uuid of the partition matches the + * HMAC-SHA256 of the /var GPT partition type uuid, keyed by machine + * ID. Why? Unlike the other partitions /var is inherently + * installation specific, hence we need to be careful not to mount it + * in the wrong installation. By hashing the partition UUID from + * /etc/machine-id we can securely bind the partition to the + * installation. */ + + r = sd_id128_get_machine_app_specific(GPT_VAR, &var_uuid); + if (r < 0) + return r; + + if (!sd_id128_equal(var_uuid, id)) { + log_debug("Found a /var/ partition, but its UUID didn't match our expectations, ignoring."); + continue; + } + } + + designator = PARTITION_VAR; + rw = !(pflags & GPT_FLAG_READ_ONLY); } if (designator != _PARTITION_DESIGNATOR_INVALID) { @@ -910,6 +947,14 @@ int dissected_image_mount(DissectedImage *m, const char *where, uid_t uid_shift, if (r < 0) return r; + r = mount_partition(m->partitions + PARTITION_VAR, where, "/var", uid_shift, flags); + if (r < 0) + return r; + + r = mount_partition(m->partitions + PARTITION_TMP, where, "/var/tmp", uid_shift, flags); + if (r < 0) + return r; + boot_mounted = mount_partition(m->partitions + PARTITION_XBOOTLDR, where, "/boot", uid_shift, flags); if (boot_mounted < 0) return boot_mounted; @@ -1333,7 +1378,8 @@ int dissected_image_acquire_metadata(DissectedImage *m) { [META_HOSTNAME] = "/etc/hostname\0", [META_MACHINE_ID] = "/etc/machine-id\0", [META_MACHINE_INFO] = "/etc/machine-info\0", - [META_OS_RELEASE] = "/etc/os-release\0/usr/lib/os-release\0", + [META_OS_RELEASE] = "/etc/os-release\0" + "/usr/lib/os-release\0", }; _cleanup_strv_free_ char **machine_info = NULL, **os_release = NULL; @@ -1528,6 +1574,8 @@ static const char *const partition_designator_table[] = { [PARTITION_SWAP] = "swap", [PARTITION_ROOT_VERITY] = "root-verity", [PARTITION_ROOT_SECONDARY_VERITY] = "root-secondary-verity", + [PARTITION_TMP] = "tmp", + [PARTITION_VAR] = "var", }; DEFINE_STRING_TABLE_LOOKUP(partition_designator, int); diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h index 40b8035ac7..359dc877d5 100644 --- a/src/shared/dissect-image.h +++ b/src/shared/dissect-image.h @@ -33,6 +33,8 @@ enum { PARTITION_SWAP, PARTITION_ROOT_VERITY, /* verity data for the PARTITION_ROOT partition */ PARTITION_ROOT_SECONDARY_VERITY, /* verity data for the PARTITION_ROOT_SECONDARY partition */ + PARTITION_TMP, + PARTITION_VAR, _PARTITION_DESIGNATOR_MAX, _PARTITION_DESIGNATOR_INVALID = -1 }; @@ -59,6 +61,7 @@ typedef enum DissectImageFlags { DISSECT_IMAGE_MOUNT_NON_ROOT_ONLY = 1 << 7, /* Mount only non-root partitions */ DISSECT_IMAGE_VALIDATE_OS = 1 << 8, /* Refuse mounting images that aren't identifiable as OS images */ DISSECT_IMAGE_NO_UDEV = 1 << 9, /* Don't wait for udev initializing things */ + DISSECT_IMAGE_RELAX_VAR_CHECK = 1 << 10, /* Don't insist that the UUID of /var is hashed from /etc/machine-id */ } DissectImageFlags; struct DissectedImage { diff --git a/src/shared/gpt.h b/src/shared/gpt.h index 31e01bd5a5..8e9b111857 100644 --- a/src/shared/gpt.h +++ b/src/shared/gpt.h @@ -19,6 +19,8 @@ #define GPT_SWAP SD_ID128_MAKE(06,57,fd,6d,a4,ab,43,c4,84,e5,09,33,c8,4b,4f,4f) #define GPT_HOME SD_ID128_MAKE(93,3a,c7,e1,2e,b4,4f,13,b8,44,0e,14,e2,ae,f9,15) #define GPT_SRV SD_ID128_MAKE(3b,8f,84,25,20,e0,4f,3b,90,7f,1a,25,a7,6f,98,e8) +#define GPT_VAR SD_ID128_MAKE(4d,21,b0,16,b5,34,45,c2,a9,fb,5c,16,e0,91,fd,2d) +#define GPT_TMP SD_ID128_MAKE(7e,c6,f5,57,3b,c5,4a,ca,b2,93,16,ef,5d,f6,39,d1) /* Verity partitions for the root partitions above (we only define them for the root partitions, because only they are * are commonly read-only and hence suitable for verity). */ diff --git a/src/shared/machine-image.c b/src/shared/machine-image.c index 15fd514353..b45efcd1e6 100644 --- a/src/shared/machine-image.c +++ b/src/shared/machine-image.c @@ -1171,7 +1171,7 @@ int image_read_metadata(Image *i) { if (r < 0) return r; - r = dissect_image(d->fd, NULL, 0, DISSECT_IMAGE_REQUIRE_ROOT, &m); + r = dissect_image(d->fd, NULL, 0, DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_RELAX_VAR_CHECK, &m); if (r < 0) return r; diff --git a/src/test/test-dissect-image.c b/src/test/test-dissect-image.c index 12685dad13..a1ccf605b1 100644 --- a/src/test/test-dissect-image.c +++ b/src/test/test-dissect-image.c @@ -28,7 +28,7 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - r = dissect_image(d->fd, NULL, 0, DISSECT_IMAGE_REQUIRE_ROOT, &m); + r = dissect_image(d->fd, NULL, 0, DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_RELAX_VAR_CHECK, &m); if (r < 0) { log_error_errno(r, "Failed to dissect image: %m"); return EXIT_FAILURE;