summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/os-release.xml12
-rw-r--r--src/core/namespace.c2
-rw-r--r--src/portable/portable.c2
-rw-r--r--src/shared/dissect-image.c14
-rw-r--r--src/shared/dissect-image.h2
-rw-r--r--src/shared/extension-release.c23
-rw-r--r--src/shared/extension-release.h1
-rw-r--r--src/shared/mount-util.c2
-rw-r--r--src/sysext/sysext.c7
9 files changed, 54 insertions, 11 deletions
diff --git a/man/os-release.xml b/man/os-release.xml
index ef5ef8b2e1..a985151b4d 100644
--- a/man/os-release.xml
+++ b/man/os-release.xml
@@ -407,6 +407,18 @@
<para>Examples: <literal>SYSEXT_LEVEL=2</literal>, <literal>SYSEXT_LEVEL=15.14</literal>.
</para></listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><varname>SYSEXT_SCOPE=</varname></term>
+ <listitem><para>Takes a space-separated list of one or more of the strings
+ <literal>system</literal>, <literal>initrd</literal> and <literal>portable</literal>. This field is
+ only supported in <filename>extension-release.d/</filename> files and indicates what environments
+ the system extension is applicable to: i.e. to regular systems, to initial RAM filesystems
+ ("initrd") or to portable service images. If unspecified, <literal>SYSEXT_SCOPE=system
+ portable</literal> is implied, i.e. any system extension without this field is applicable to
+ regular systems and to portable service environments, but not to initrd
+ environments.</para></listitem>
+ </varlistentry>
</variablelist>
</refsect2>
diff --git a/src/core/namespace.c b/src/core/namespace.c
index c8e7e65e27..9393a202c4 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -1149,7 +1149,7 @@ static int mount_image(const MountEntry *m, const char *root_directory) {
r = verity_dissect_and_mount(
mount_entry_source(m), mount_entry_path(m), m->image_options,
- host_os_release_id, host_os_release_version_id, host_os_release_sysext_level);
+ host_os_release_id, host_os_release_version_id, host_os_release_sysext_level, NULL);
if (r == -ENOENT && m->ignore)
return 0;
if (r == -ESTALE && host_os_release_id)
diff --git a/src/portable/portable.c b/src/portable/portable.c
index 8ccb8f5228..612893b688 100644
--- a/src/portable/portable.c
+++ b/src/portable/portable.c
@@ -595,7 +595,7 @@ static int extract_image_and_extensions(
if (r < 0)
return r;
- r = extension_release_validate(ext->path, id, version_id, sysext_level, extension_release);
+ r = extension_release_validate(ext->path, id, version_id, sysext_level, "portable", extension_release);
if (r == 0)
return sd_bus_error_set_errnof(error, SYNTHETIC_ERRNO(ESTALE), "Image %s extension-release metadata does not match the root's", ext->path);
if (r < 0)
diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c
index b92df413a9..06d0319f75 100644
--- a/src/shared/dissect-image.c
+++ b/src/shared/dissect-image.c
@@ -3525,7 +3525,8 @@ int verity_dissect_and_mount(
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) {
+ const char *required_host_os_release_sysext_level,
+ const char *required_sysext_scope) {
_cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
_cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_image = NULL;
@@ -3611,11 +3612,12 @@ int verity_dissect_and_mount(
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);
+ dissected_image->image_name,
+ required_host_os_release_id,
+ required_host_os_release_version_id,
+ required_host_os_release_sysext_level,
+ required_sysext_scope,
+ 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)
diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h
index b75b86ab99..8ad26bc45b 100644
--- a/src/shared/dissect-image.h
+++ b/src/shared/dissect-image.h
@@ -228,4 +228,4 @@ bool dissected_image_verity_sig_ready(const DissectedImage *image, PartitionDesi
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, const char *required_host_os_release_id, const char *required_host_os_release_version_id, const char *required_host_os_release_sysext_level);
+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, const char *required_sysext_scope);
diff --git a/src/shared/extension-release.c b/src/shared/extension-release.c
index 29cbecbf57..dccc999907 100644
--- a/src/shared/extension-release.c
+++ b/src/shared/extension-release.c
@@ -12,6 +12,7 @@ int extension_release_validate(
const char *host_os_release_id,
const char *host_os_release_version_id,
const char *host_os_release_sysext_level,
+ const char *host_sysext_scope,
char **extension_release) {
const char *extension_release_id = NULL, *extension_release_sysext_level = NULL;
@@ -25,6 +26,28 @@ int extension_release_validate(
return 0;
}
+ if (host_sysext_scope) {
+ _cleanup_strv_free_ char **extension_sysext_scope_list = NULL;
+ const char *extension_sysext_scope;
+ bool valid;
+
+ extension_sysext_scope = strv_env_pairs_get(extension_release, "SYSEXT_SCOPE");
+ if (extension_sysext_scope) {
+ extension_sysext_scope_list = strv_split(extension_sysext_scope, WHITESPACE);
+ if (!extension_sysext_scope_list)
+ return -ENOMEM;
+ }
+
+ /* by default extension are good for attachment in portable service and on the system */
+ valid = strv_contains(
+ extension_sysext_scope_list ?: STRV_MAKE("system", "portable"),
+ host_sysext_scope);
+ if (!valid) {
+ log_debug("Extension '%s' is not suitable for scope %s, ignoring extension.", name, host_sysext_scope);
+ return 0;
+ }
+ }
+
extension_release_id = strv_env_pairs_get(extension_release, "ID");
if (isempty(extension_release_id)) {
log_debug("Extension '%s' does not contain ID in extension-release but requested to match '%s'",
diff --git a/src/shared/extension-release.h b/src/shared/extension-release.h
index d026a9b225..5c3fee24be 100644
--- a/src/shared/extension-release.h
+++ b/src/shared/extension-release.h
@@ -9,6 +9,7 @@ int extension_release_validate(
const char *host_os_release_id,
const char *host_os_release_version_id,
const char *host_os_release_sysext_level,
+ const char *host_sysext_scope,
char **extension_release);
/* Parse SYSTEMD_SYSEXT_HIERARCHIES and if not set, return "/usr /opt" */
diff --git a/src/shared/mount-util.c b/src/shared/mount-util.c
index 8d4a6cd25a..c75c02f5be 100644
--- a/src/shared/mount-util.c
+++ b/src/shared/mount-util.c
@@ -874,7 +874,7 @@ static int mount_in_namespace(
mount_tmp_created = true;
if (is_image)
- r = verity_dissect_and_mount(FORMAT_PROC_FD_PATH(chased_src_fd), mount_tmp, options, NULL, NULL, NULL);
+ r = verity_dissect_and_mount(FORMAT_PROC_FD_PATH(chased_src_fd), mount_tmp, options, NULL, NULL, NULL, NULL);
else
r = mount_follow_verbose(LOG_DEBUG, FORMAT_PROC_FD_PATH(chased_src_fd), mount_tmp, NULL, MS_BIND, NULL);
if (r < 0)
diff --git a/src/sysext/sysext.c b/src/sysext/sysext.c
index b9387e904a..5abf1bb418 100644
--- a/src/sysext/sysext.c
+++ b/src/sysext/sysext.c
@@ -432,12 +432,17 @@ static int validate_version(
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Extension image contains /usr/lib/os-release file, which is not allowed (it may carry /etc/os-release), refusing.");
- return extension_release_validate(
+ r = extension_release_validate(
img->name,
host_os_release_id,
host_os_release_version_id,
host_os_release_sysext_level,
+ in_initrd() ? "initrd" : "system",
img->extension_release);
+ if (r < 0)
+ return log_error_errno(r, "Failed to validate extension release information: %m");
+
+ return r;
}
static int merge_subprocess(Hashmap *images, const char *workspace) {