Merge pull request #18018 from bluca/mount_images_overlay

Add ExtensionImages directive to form overlays
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2021-02-25 11:31:14 +01:00
committed by GitHub
23 changed files with 921 additions and 167 deletions
+104
View File
@@ -1766,6 +1766,110 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
return 1;
}
if (streq(field, "ExtensionImages")) {
const char *p = eq;
r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
if (r < 0)
return bus_log_create_error(r);
r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
if (r < 0)
return bus_log_create_error(r);
r = sd_bus_message_open_container(m, 'v', "a(sba(ss))");
if (r < 0)
return bus_log_create_error(r);
r = sd_bus_message_open_container(m, 'a', "(sba(ss))");
if (r < 0)
return bus_log_create_error(r);
for (;;) {
_cleanup_free_ char *source = NULL, *tuple = NULL;
const char *q = NULL, *s = NULL;
bool permissive = false;
r = extract_first_word(&p, &tuple, NULL, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE);
if (r < 0)
return r;
if (r == 0)
break;
q = tuple;
r = extract_first_word(&q, &source, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS);
if (r < 0)
return r;
if (r == 0)
continue;
s = source;
if (s[0] == '-') {
permissive = true;
s++;
}
r = sd_bus_message_open_container(m, 'r', "sba(ss)");
if (r < 0)
return bus_log_create_error(r);
r = sd_bus_message_append(m, "sb", s, permissive);
if (r < 0)
return bus_log_create_error(r);
r = sd_bus_message_open_container(m, 'a', "(ss)");
if (r < 0)
return bus_log_create_error(r);
for (;;) {
_cleanup_free_ char *partition = NULL, *mount_options = NULL;
r = extract_many_words(&q, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &partition, &mount_options, NULL);
if (r < 0)
return r;
if (r == 0)
break;
/* Single set of options, applying to the root partition/single filesystem */
if (r == 1) {
r = sd_bus_message_append(m, "(ss)", "root", partition);
if (r < 0)
return bus_log_create_error(r);
break;
}
if (partition_designator_from_string(partition) < 0)
return bus_log_create_error(-EINVAL);
r = sd_bus_message_append(m, "(ss)", partition, mount_options);
if (r < 0)
return bus_log_create_error(r);
}
r = sd_bus_message_close_container(m);
if (r < 0)
return bus_log_create_error(r);
r = sd_bus_message_close_container(m);
if (r < 0)
return bus_log_create_error(r);
}
r = sd_bus_message_close_container(m);
if (r < 0)
return bus_log_create_error(r);
r = sd_bus_message_close_container(m);
if (r < 0)
return bus_log_create_error(r);
r = sd_bus_message_close_container(m);
if (r < 0)
return bus_log_create_error(r);
return 1;
}
return 0;
}
+33 -1
View File
@@ -27,6 +27,7 @@
#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"
@@ -2621,7 +2622,14 @@ static const char *const partition_designator_table[] = {
[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;
@@ -2683,6 +2691,30 @@ int verity_dissect_and_mount(const char *src, const char *dest, const MountOptio
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)
+1 -1
View File
@@ -164,4 +164,4 @@ bool dissected_image_has_verity(const DissectedImage *image, PartitionDesignator
int mount_image_privately_interactively(const char *path, DissectImageFlags flags, char **ret_directory, LoopDevice **ret_loop_device, DecryptedImage **ret_decrypted_image);
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);
+15
View File
@@ -77,3 +77,18 @@ int extension_release_validate(
log_debug("Version info of extension '%s' matches host.", name);
return 1;
}
int parse_env_extension_hierarchies(char ***ret_hierarchies) {
int r;
r = getenv_path_list("SYSTEMD_SYSEXT_HIERARCHIES", ret_hierarchies);
if (r < 0)
return log_debug_errno(r, "Failed to parse SYSTEMD_SYSEXT_HIERARCHIES environment variable : %m");
if (!*ret_hierarchies) {
*ret_hierarchies = strv_new("/usr", "/opt");
if (!*ret_hierarchies)
return -ENOMEM;
}
return 0;
}
+3
View File
@@ -10,3 +10,6 @@ int extension_release_validate(
const char *host_os_release_version_id,
const char *host_os_release_sysext_level,
char **extension_release);
/* Parse SYSTEMD_SYSEXT_HIERARCHIES and if not set, return "/usr /opt" */
int parse_env_extension_hierarchies(char ***ret_hierarchies);
+1 -1
View File
@@ -855,7 +855,7 @@ static int mount_in_namespace(
mount_tmp_created = true;
if (is_image)
r = verity_dissect_and_mount(chased_src, mount_tmp, options);
r = verity_dissect_and_mount(chased_src, mount_tmp, options, NULL, NULL, NULL);
else
r = mount_follow_verbose(LOG_DEBUG, chased_src, mount_tmp, NULL, MS_BIND, NULL);
if (r < 0)