X Tutup
Skip to content

Commit 60c5f70

Browse files
committed
extension-release.d/: add a new field SYSEXT_SCOPE= for clarifying what a system extension is for
This should make things a bit more robust since it ensures system extension can only applied to the right environments. Right now three different "scopes" are defined: 1. "system" (for regular OS systems, after the initrd transition) 2. "initrd" (for sysext images that apply to the initrd environment) 3. "portable" (for sysext images that apply to portable images) If not specified we imply a default of "system portable", i.e. any image where the field is not specified is implicitly OK for application to OS images and for portable services – but not for initrds.
1 parent a4e0d61 commit 60c5f70

File tree

9 files changed

+54
-11
lines changed

9 files changed

+54
-11
lines changed

man/os-release.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,18 @@
407407
<para>Examples: <literal>SYSEXT_LEVEL=2</literal>, <literal>SYSEXT_LEVEL=15.14</literal>.
408408
</para></listitem>
409409
</varlistentry>
410+
411+
<varlistentry>
412+
<term><varname>SYSEXT_SCOPE=</varname></term>
413+
<listitem><para>Takes a space-separated list of one or more of the strings
414+
<literal>system</literal>, <literal>initrd</literal> and <literal>portable</literal>. This field is
415+
only supported in <filename>extension-release.d/</filename> files and indicates what environments
416+
the system extension is applicable to: i.e. to regular systems, to initial RAM filesystems
417+
("initrd") or to portable service images. If unspecified, <literal>SYSEXT_SCOPE=system
418+
portable</literal> is implied, i.e. any system extension without this field is applicable to
419+
regular systems and to portable service environments, but not to initrd
420+
environments.</para></listitem>
421+
</varlistentry>
410422
</variablelist>
411423
</refsect2>
412424

src/core/namespace.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1149,7 +1149,7 @@ static int mount_image(const MountEntry *m, const char *root_directory) {
11491149

11501150
r = verity_dissect_and_mount(
11511151
mount_entry_source(m), mount_entry_path(m), m->image_options,
1152-
host_os_release_id, host_os_release_version_id, host_os_release_sysext_level);
1152+
host_os_release_id, host_os_release_version_id, host_os_release_sysext_level, NULL);
11531153
if (r == -ENOENT && m->ignore)
11541154
return 0;
11551155
if (r == -ESTALE && host_os_release_id)

src/portable/portable.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,7 @@ static int extract_image_and_extensions(
595595
if (r < 0)
596596
return r;
597597

598-
r = extension_release_validate(ext->path, id, version_id, sysext_level, extension_release);
598+
r = extension_release_validate(ext->path, id, version_id, sysext_level, "portable", extension_release);
599599
if (r == 0)
600600
return sd_bus_error_set_errnof(error, SYNTHETIC_ERRNO(ESTALE), "Image %s extension-release metadata does not match the root's", ext->path);
601601
if (r < 0)

src/shared/dissect-image.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3525,7 +3525,8 @@ int verity_dissect_and_mount(
35253525
const MountOptions *options,
35263526
const char *required_host_os_release_id,
35273527
const char *required_host_os_release_version_id,
3528-
const char *required_host_os_release_sysext_level) {
3528+
const char *required_host_os_release_sysext_level,
3529+
const char *required_sysext_scope) {
35293530

35303531
_cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
35313532
_cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_image = NULL;
@@ -3611,11 +3612,12 @@ int verity_dissect_and_mount(
36113612
return log_debug_errno(r, "Failed to parse image %s extension-release metadata: %m", dissected_image->image_name);
36123613

36133614
r = extension_release_validate(
3614-
dissected_image->image_name,
3615-
required_host_os_release_id,
3616-
required_host_os_release_version_id,
3617-
required_host_os_release_sysext_level,
3618-
extension_release);
3615+
dissected_image->image_name,
3616+
required_host_os_release_id,
3617+
required_host_os_release_version_id,
3618+
required_host_os_release_sysext_level,
3619+
required_sysext_scope,
3620+
extension_release);
36193621
if (r == 0)
36203622
return log_debug_errno(SYNTHETIC_ERRNO(ESTALE), "Image %s extension-release metadata does not match the root's", dissected_image->image_name);
36213623
if (r < 0)

src/shared/dissect-image.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,4 +228,4 @@ bool dissected_image_verity_sig_ready(const DissectedImage *image, PartitionDesi
228228

229229
int mount_image_privately_interactively(const char *path, DissectImageFlags flags, char **ret_directory, LoopDevice **ret_loop_device, DecryptedImage **ret_decrypted_image);
230230

231-
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);
231+
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);

src/shared/extension-release.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ int extension_release_validate(
1212
const char *host_os_release_id,
1313
const char *host_os_release_version_id,
1414
const char *host_os_release_sysext_level,
15+
const char *host_sysext_scope,
1516
char **extension_release) {
1617

1718
const char *extension_release_id = NULL, *extension_release_sysext_level = NULL;
@@ -25,6 +26,28 @@ int extension_release_validate(
2526
return 0;
2627
}
2728

29+
if (host_sysext_scope) {
30+
_cleanup_strv_free_ char **extension_sysext_scope_list = NULL;
31+
const char *extension_sysext_scope;
32+
bool valid;
33+
34+
extension_sysext_scope = strv_env_pairs_get(extension_release, "SYSEXT_SCOPE");
35+
if (extension_sysext_scope) {
36+
extension_sysext_scope_list = strv_split(extension_sysext_scope, WHITESPACE);
37+
if (!extension_sysext_scope_list)
38+
return -ENOMEM;
39+
}
40+
41+
/* by default extension are good for attachment in portable service and on the system */
42+
valid = strv_contains(
43+
extension_sysext_scope_list ?: STRV_MAKE("system", "portable"),
44+
host_sysext_scope);
45+
if (!valid) {
46+
log_debug("Extension '%s' is not suitable for scope %s, ignoring extension.", name, host_sysext_scope);
47+
return 0;
48+
}
49+
}
50+
2851
extension_release_id = strv_env_pairs_get(extension_release, "ID");
2952
if (isempty(extension_release_id)) {
3053
log_debug("Extension '%s' does not contain ID in extension-release but requested to match '%s'",

src/shared/extension-release.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ int extension_release_validate(
99
const char *host_os_release_id,
1010
const char *host_os_release_version_id,
1111
const char *host_os_release_sysext_level,
12+
const char *host_sysext_scope,
1213
char **extension_release);
1314

1415
/* Parse SYSTEMD_SYSEXT_HIERARCHIES and if not set, return "/usr /opt" */

src/shared/mount-util.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -874,7 +874,7 @@ static int mount_in_namespace(
874874
mount_tmp_created = true;
875875

876876
if (is_image)
877-
r = verity_dissect_and_mount(FORMAT_PROC_FD_PATH(chased_src_fd), mount_tmp, options, NULL, NULL, NULL);
877+
r = verity_dissect_and_mount(FORMAT_PROC_FD_PATH(chased_src_fd), mount_tmp, options, NULL, NULL, NULL, NULL);
878878
else
879879
r = mount_follow_verbose(LOG_DEBUG, FORMAT_PROC_FD_PATH(chased_src_fd), mount_tmp, NULL, MS_BIND, NULL);
880880
if (r < 0)

src/sysext/sysext.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,12 +432,17 @@ static int validate_version(
432432
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
433433
"Extension image contains /usr/lib/os-release file, which is not allowed (it may carry /etc/os-release), refusing.");
434434

435-
return extension_release_validate(
435+
r = extension_release_validate(
436436
img->name,
437437
host_os_release_id,
438438
host_os_release_version_id,
439439
host_os_release_sysext_level,
440+
in_initrd() ? "initrd" : "system",
440441
img->extension_release);
442+
if (r < 0)
443+
return log_error_errno(r, "Failed to validate extension release information: %m");
444+
445+
return r;
441446
}
442447

443448
static int merge_subprocess(Hashmap *images, const char *workspace) {

0 commit comments

Comments
 (0)
X Tutup