summaryrefslogtreecommitdiff
path: root/src/sysext
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2023-04-12 13:46:08 +0200
committerGitHub <noreply@github.com>2023-04-12 13:46:08 +0200
commit3af48a86d99b3117a44bc22258ab4d34d0ba7655 (patch)
tree594af3dadad0f5a0febfb73137689eea7503fe83 /src/sysext
parent068943453f94c7e44a7b09972ae0cde09080aa95 (diff)
parent3bcf564530bfa7e001354dd94e653905523c418d (diff)
downloadsystemd-3af48a86d99b3117a44bc22258ab4d34d0ba7655.tar.gz
Merge pull request #25608 from poettering/dissect-moar
dissect: add dissection policies
Diffstat (limited to 'src/sysext')
-rw-r--r--src/sysext/sysext.c54
1 files changed, 45 insertions, 9 deletions
diff --git a/src/sysext/sysext.c b/src/sysext/sysext.c
index d235073743..3fc6b910c4 100644
--- a/src/sysext/sysext.c
+++ b/src/sysext/sysext.c
@@ -45,12 +45,14 @@ static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF;
static PagerFlags arg_pager_flags = 0;
static bool arg_legend = true;
static bool arg_force = false;
+static ImagePolicy *arg_image_policy = NULL;
/* Is set to IMAGE_CONFEXT when systemd is called with the confext functionality instead of the default */
static ImageClass arg_image_class = IMAGE_SYSEXT;
STATIC_DESTRUCTOR_REGISTER(arg_hierarchies, strv_freep);
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
+STATIC_DESTRUCTOR_REGISTER(arg_image_policy, image_policy_freep);
/* Helper struct for naming simplicity and reusability */
static const struct {
@@ -441,6 +443,24 @@ static int strverscmp_improvedp(char *const* a, char *const* b) {
return strverscmp_improved(*a, *b);
}
+static const ImagePolicy *pick_image_policy(const Image *img) {
+ assert(img);
+ assert(img->path);
+
+ /* Explicitly specified policy always wins */
+ if (arg_image_policy)
+ return arg_image_policy;
+
+ /* If located in /.extra/sysext/ in the initrd, then it was placed there by systemd-stub, and was
+ * picked up from an untrusted ESP. Thus, require a stricter policy by default for them. (For the
+ * other directories we assume the appropriate level of trust was already established already. */
+
+ if (in_initrd() && path_startswith(img->path, "/.extra/sysext/"))
+ return &image_policy_sysext_strict;
+
+ return &image_policy_sysext;
+}
+
static int merge_subprocess(Hashmap *images, const char *workspace) {
_cleanup_free_ char *host_os_release_id = NULL, *host_os_release_version_id = NULL, *host_os_release_sysext_level = NULL,
*host_os_release_confext_level = NULL, *buf = NULL;
@@ -558,7 +578,8 @@ static int merge_subprocess(Hashmap *images, const char *workspace) {
r = dissect_loop_device_and_warn(
d,
&verity_settings,
- NULL,
+ /* mount_options= */ NULL,
+ pick_image_policy(img),
flags,
&m);
if (r < 0)
@@ -770,7 +791,7 @@ static int image_discover_and_read_metadata(Hashmap **ret_images) {
return log_error_errno(r, "Failed to discover images: %m");
HASHMAP_FOREACH(img, images) {
- r = image_read_metadata(img);
+ r = image_read_metadata(img, &image_policy_sysext);
if (r < 0)
return log_error_errno(r, "Failed to read metadata for image %s: %m", img->name);
}
@@ -922,6 +943,8 @@ static int verb_help(int argc, char **argv, void *userdata) {
" --json=pretty|short|off\n"
" Generate JSON output\n"
" --force Ignore version incompatibilities\n"
+ " --image-policy=POLICY\n"
+ " Specify disk image dissection policy\n"
"\nSee the %2$s for details.\n",
program_invocation_short_name,
link,
@@ -942,16 +965,18 @@ static int parse_argv(int argc, char *argv[]) {
ARG_ROOT,
ARG_JSON,
ARG_FORCE,
+ ARG_IMAGE_POLICY,
};
static const struct option options[] = {
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, ARG_VERSION },
- { "no-pager", no_argument, NULL, ARG_NO_PAGER },
- { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
- { "root", required_argument, NULL, ARG_ROOT },
- { "json", required_argument, NULL, ARG_JSON },
- { "force", no_argument, NULL, ARG_FORCE },
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, ARG_VERSION },
+ { "no-pager", no_argument, NULL, ARG_NO_PAGER },
+ { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
+ { "root", required_argument, NULL, ARG_ROOT },
+ { "json", required_argument, NULL, ARG_JSON },
+ { "force", no_argument, NULL, ARG_FORCE },
+ { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY },
{}
};
@@ -995,6 +1020,17 @@ static int parse_argv(int argc, char *argv[]) {
arg_force = true;
break;
+ case ARG_IMAGE_POLICY: {
+ _cleanup_(image_policy_freep) ImagePolicy *p = NULL;
+
+ r = image_policy_from_string(optarg, &p);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse image policy: %s", optarg);
+
+ image_policy_free(arg_image_policy);
+ arg_image_policy = TAKE_PTR(p);
+ break;
+ }
case '?':
return -EINVAL;