diff options
-rw-r--r-- | src/dissect/dissect.c | 4 | ||||
-rw-r--r-- | src/machine/image-dbus.c | 2 | ||||
-rw-r--r-- | src/nspawn/nspawn.c | 6 | ||||
-rw-r--r-- | src/shared/dissect-image.c | 25 | ||||
-rw-r--r-- | src/shared/dissect-image.h | 1 | ||||
-rw-r--r-- | src/test/test-dissect-image.c | 2 |
6 files changed, 27 insertions, 13 deletions
diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c index 78ec88fa35..fd9db5ba87 100644 --- a/src/dissect/dissect.c +++ b/src/dissect/dissect.c @@ -35,7 +35,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_DISCARD_ON_LOOP; +static DissectImageFlags arg_flags = DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_DISCARD_ON_LOOP; static void *arg_root_hash = NULL; static size_t arg_root_hash_size = 0; @@ -191,7 +191,7 @@ int main(int argc, char *argv[]) { goto finish; } - r = dissect_image(d->fd, arg_root_hash, arg_root_hash_size, 0, &m); + r = dissect_image(d->fd, arg_root_hash, arg_root_hash_size, arg_flags, &m); if (r == -ENOPKG) { log_error_errno(r, "Couldn't identify a suitable partition table or file system in %s.", arg_image); goto finish; diff --git a/src/machine/image-dbus.c b/src/machine/image-dbus.c index 2b168b267b..1891f07586 100644 --- a/src/machine/image-dbus.c +++ b/src/machine/image-dbus.c @@ -336,7 +336,7 @@ static int raw_image_get_os_release(Image *image, char ***ret, sd_bus_error *err if (r < 0) return sd_bus_error_set_errnof(error, r, "Failed to set up loop block device for %s: %m", image->path); - r = dissect_image(d->fd, NULL, 0, 0, &m); + r = dissect_image(d->fd, NULL, 0, DISSECT_IMAGE_REQUIRE_ROOT, &m); if (r == -ENOPKG) return sd_bus_error_set_errnof(error, r, "Disk image %s not understood: %m", image->path); if (r < 0) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 01d89df1a4..224d30fca6 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -3743,7 +3743,11 @@ int main(int argc, char *argv[]) { goto finish; } - r = dissect_image(loop->fd, arg_root_hash, arg_root_hash_size, 0, &dissected_image); + r = dissect_image( + loop->fd, + arg_root_hash, arg_root_hash_size, + DISSECT_IMAGE_REQUIRE_ROOT, + &dissected_image); if (r == -ENOPKG) { log_error_errno(r, "Could not find a suitable file system or partition table in image: %s", arg_image); diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 5b6e78dd3d..878cb008aa 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -174,7 +174,8 @@ int dissect_image(int fd, const void *root_hash, size_t root_hash_size, DissectI if (!m) return -ENOMEM; - if ((flags & DISSECT_IMAGE_GPT_ONLY) == 0) { + if (!(flags & DISSECT_IMAGE_GPT_ONLY) && + (flags & DISSECT_IMAGE_REQUIRE_ROOT)) { const char *usage = NULL; (void) blkid_probe_lookup_value(b, "USAGE", &usage, NULL); @@ -490,7 +491,7 @@ int dissect_image(int fd, const void *root_hash, size_t root_hash_size, DissectI * either, then check if there's a single generic one, and use that. */ if (m->partitions[PARTITION_ROOT_VERITY].found) - return -ENXIO; + return -EADDRNOTAVAIL; if (m->partitions[PARTITION_ROOT_SECONDARY].found) { m->partitions[PARTITION_ROOT] = m->partitions[PARTITION_ROOT_SECONDARY]; @@ -499,8 +500,19 @@ int dissect_image(int fd, const void *root_hash, size_t root_hash_size, DissectI m->partitions[PARTITION_ROOT_VERITY] = m->partitions[PARTITION_ROOT_SECONDARY_VERITY]; zero(m->partitions[PARTITION_ROOT_SECONDARY_VERITY]); - } else if (generic_node && !root_hash) { + } else if (flags & DISSECT_IMAGE_REQUIRE_ROOT) { + + /* If the root has was set, then we won't fallback to a generic node, because the root hash + * decides */ + if (root_hash) + return -EADDRNOTAVAIL; + /* If we didn't find a generic node, then we can't fix this up either */ + if (!generic_node) + return -ENXIO; + + /* If we didn't find a properly marked root partition, but we did find a single suitable + * generic Linux partition, then use this as root partition, if the caller asked for it. */ if (multiple_generic) return -ENOTUNIQ; @@ -514,14 +526,11 @@ int dissect_image(int fd, const void *root_hash, size_t root_hash_size, DissectI }; generic_node = NULL; - } else - return -ENXIO; + } } - assert(m->partitions[PARTITION_ROOT].found); - if (root_hash) { - if (!m->partitions[PARTITION_ROOT_VERITY].found) + if (!m->partitions[PARTITION_ROOT_VERITY].found || !m->partitions[PARTITION_ROOT].found) return -EADDRNOTAVAIL; /* If we found the primary root with the hash, then we definitely want to suppress any secondary root diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h index 76104e5780..26319bd8e7 100644 --- a/src/shared/dissect-image.h +++ b/src/shared/dissect-image.h @@ -69,6 +69,7 @@ typedef enum DissectImageFlags { DISSECT_IMAGE_DISCARD | DISSECT_IMAGE_DISCARD_ON_CRYPTO, DISSECT_IMAGE_GPT_ONLY = 16, /* Only recognize images with GPT partition tables */ + DISSECT_IMAGE_REQUIRE_ROOT = 32, /* Don't accept disks without root partition */ } DissectImageFlags; struct DissectedImage { diff --git a/src/test/test-dissect-image.c b/src/test/test-dissect-image.c index ddaf3a0d8b..2bb68be0db 100644 --- a/src/test/test-dissect-image.c +++ b/src/test/test-dissect-image.c @@ -43,7 +43,7 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - r = dissect_image(d->fd, NULL, 0, 0, &m); + r = dissect_image(d->fd, NULL, 0, DISSECT_IMAGE_REQUIRE_ROOT, &m); if (r < 0) { log_error_errno(r, "Failed to dissect image: %m"); return EXIT_FAILURE; |