sysext: validate that they do not contain os-release

sysexts are not supposed to ship os-release files, enforce this
when loading them
This commit is contained in:
Luca Boccassi
2023-03-30 11:28:12 +01:00
parent de862276ed
commit 6afa5d862e
6 changed files with 88 additions and 57 deletions
+11
View File
@@ -22,6 +22,7 @@
#include "dissect-image.h"
#include "env-file.h"
#include "env-util.h"
#include "extension-util.h"
#include "fd-util.h"
#include "fs-util.h"
#include "hashmap.h"
@@ -1151,6 +1152,16 @@ int image_read_metadata(Image *i) {
_cleanup_free_ char *hostname = NULL;
_cleanup_free_ char *path = NULL;
if (i->class == IMAGE_EXTENSION) {
r = extension_has_forbidden_content(i->path);
if (r < 0)
return r;
if (r > 0)
return log_debug_errno(SYNTHETIC_ERRNO(ENOMEDIUM),
"Conflicting content found in image %s, refusing.",
i->name);
}
r = chase("/etc/hostname", i->path, CHASE_PREFIX_ROOT|CHASE_TRAIL_SLASH, &path, NULL);
if (r < 0 && r != -ENOENT)
log_debug_errno(r, "Failed to chase /etc/hostname in image %s: %m", i->name);
+8 -3
View File
@@ -1787,11 +1787,16 @@ int dissected_image_mount(
ok = true;
}
if (!ok && FLAGS_SET(flags, DISSECT_IMAGE_VALIDATE_OS_EXT)) {
r = path_is_extension_tree(where, m->image_name, FLAGS_SET(flags, DISSECT_IMAGE_RELAX_SYSEXT_CHECK));
r = extension_has_forbidden_content(where);
if (r < 0)
return r;
if (r > 0)
ok = true;
if (r == 0) {
r = path_is_extension_tree(where, m->image_name, FLAGS_SET(flags, DISSECT_IMAGE_RELAX_SYSEXT_CHECK));
if (r < 0)
return r;
if (r > 0)
ok = true;
}
}
if (!ok)
+18
View File
@@ -2,6 +2,7 @@
#include "alloc-util.h"
#include "architecture.h"
#include "chase.h"
#include "env-util.h"
#include "extension-util.h"
#include "log.h"
@@ -135,3 +136,20 @@ int parse_env_extension_hierarchies(char ***ret_hierarchies) {
*ret_hierarchies = TAKE_PTR(l);
return 0;
}
int extension_has_forbidden_content(const char *root) {
int r;
/* Insist that extension images do not overwrite the underlying OS release file (it's fine if
* they place one in /etc/os-release, i.e. where things don't matter, as they aren't
* merged.) */
r = chase("/usr/lib/os-release", root, CHASE_PREFIX_ROOT, NULL, NULL);
if (r > 0) {
log_debug("Extension contains '/usr/lib/os-release', which is not allowed, refusing.");
return 1;
}
if (r < 0 && r != -ENOENT)
return log_debug_errno(r, "Failed to determine whether '/usr/lib/os-release' exists in the extension: %m");
return 0;
}
+4
View File
@@ -14,3 +14,7 @@ int extension_release_validate(
/* Parse SYSTEMD_SYSEXT_HIERARCHIES and if not set, return "/usr /opt" */
int parse_env_extension_hierarchies(char ***ret_hierarchies);
/* Insist that extension images do not overwrite the underlying OS release file (it's fine if they place one
* in /etc/os-release, i.e. where things don't matter, as they aren't merged.) */
int extension_has_forbidden_content(const char *root);