#include "dissect-image.h"
#include "dm-util.h"
#include "env-file.h"
+#include "extension-release.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
DecryptedImage* decrypted_image_unref(DecryptedImage* d) {
#if HAVE_LIBCRYPTSETUP
- size_t i;
int r;
if (!d)
return NULL;
- for (i = 0; i < d->n_decrypted; i++) {
+ for (size_t i = 0; i < d->n_decrypted; i++) {
DecryptedPartition *p = d->decrypted + i;
if (p->device && p->name && !p->relinquished) {
}
int decrypted_image_relinquish(DecryptedImage *d) {
-
-#if HAVE_LIBCRYPTSETUP
- size_t i;
- int r;
-#endif
-
assert(d);
- /* Turns on automatic removal after the last use ended for all DM devices of this image, and sets a boolean so
- * that we don't clean it up ourselves either anymore */
+ /* Turns on automatic removal after the last use ended for all DM devices of this image, and sets a
+ * boolean so that we don't clean it up ourselves either anymore */
#if HAVE_LIBCRYPTSETUP
- for (i = 0; i < d->n_decrypted; i++) {
+ int r;
+
+ for (size_t i = 0; i < d->n_decrypted; i++) {
DecryptedPartition *p = d->decrypted + i;
if (p->relinquished)
_cleanup_(sigkill_waitp) pid_t child = 0;
sd_id128_t machine_id = SD_ID128_NULL;
_cleanup_free_ char *hostname = NULL;
- unsigned n_meta_initialized = 0, k;
+ unsigned n_meta_initialized = 0;
int fds[2 * _META_MAX], r, v;
ssize_t n;
_exit(EXIT_FAILURE);
}
- for (k = 0; k < _META_MAX; k++) {
+ for (unsigned k = 0; k < _META_MAX; k++) {
_cleanup_close_ int fd = -ENOENT;
const char *p;
continue;
}
- r = copy_bytes(fd, fds[2*k+1], (uint64_t) -1, 0);
+ r = copy_bytes(fd, fds[2*k+1], UINT64_MAX, 0);
if (r < 0) {
(void) write(error_pipe[1], &r, sizeof(r));
_exit(EXIT_FAILURE);
error_pipe[1] = safe_close(error_pipe[1]);
- for (k = 0; k < _META_MAX; k++) {
+ for (unsigned k = 0; k < _META_MAX; k++) {
_cleanup_fclose_ FILE *f = NULL;
if (!paths[k])
strv_free_and_replace(m->extension_release, extension_release);
finish:
- for (k = 0; k < n_meta_initialized; k++)
+ for (unsigned k = 0; k < n_meta_initialized; k++)
safe_close_pair(fds + 2*k);
return r;
[PARTITION_VAR] = "var",
};
-int verity_dissect_and_mount(const char *src, const char *dest, const MountOptions *options) {
+int verity_dissect_and_mount(
+ const char *src,
+ const char *dest,
+ const MountOptions *options,
+ const char *required_host_os_release_id,
+ const char *required_host_os_release_version_id,
+ const char *required_host_os_release_sysext_level) {
+
_cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
_cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_image = NULL;
_cleanup_(dissected_image_unrefp) DissectedImage *dissected_image = NULL;
if (r < 0)
return log_debug_errno(r, "Failed to mount image: %m");
+ /* If we got os-release values from the caller, then we need to match them with the image's
+ * extension-release.d/ content. Return -EINVAL if there's any mismatch.
+ * First, check the distro ID. If that matches, then check the new SYSEXT_LEVEL value if
+ * available, or else fallback to VERSION_ID. */
+ if (required_host_os_release_id &&
+ (required_host_os_release_version_id || required_host_os_release_sysext_level)) {
+ _cleanup_strv_free_ char **extension_release = NULL;
+
+ r = load_extension_release_pairs(dest, dissected_image->image_name, &extension_release);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to parse image %s extension-release metadata: %m", dissected_image->image_name);
+
+ r = extension_release_validate(
+ dissected_image->image_name,
+ required_host_os_release_id,
+ required_host_os_release_version_id,
+ required_host_os_release_sysext_level,
+ extension_release);
+ if (r == 0)
+ return log_debug_errno(SYNTHETIC_ERRNO(ESTALE), "Image %s extension-release metadata does not match the root's", dissected_image->image_name);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to compare image %s extension-release metadata with the root's os-release: %m", dissected_image->image_name);
+ }
+
if (decrypted_image) {
r = decrypted_image_relinquish(decrypted_image);
if (r < 0)