From 84be0c710d9d562f6d2cf986cc2a8ff4c98a138b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 30 Nov 2022 18:43:18 +0100 Subject: tree-wide: hook up image dissection policy logic everywhere --- src/analyze/analyze.c | 18 ++++++++++++++++++ src/analyze/analyze.h | 1 + 2 files changed, 19 insertions(+) (limited to 'src/analyze') diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c index 0246da4b45..8bc533b20d 100644 --- a/src/analyze/analyze.c +++ b/src/analyze/analyze.c @@ -109,6 +109,7 @@ bool arg_quiet = false; char *arg_profile = NULL; bool arg_legend = true; bool arg_table = false; +ImagePolicy *arg_image_policy = NULL; STATIC_DESTRUCTOR_REGISTER(arg_dot_from_patterns, strv_freep); STATIC_DESTRUCTOR_REGISTER(arg_dot_to_patterns, strv_freep); @@ -117,6 +118,7 @@ STATIC_DESTRUCTOR_REGISTER(arg_image, freep); STATIC_DESTRUCTOR_REGISTER(arg_security_policy, freep); STATIC_DESTRUCTOR_REGISTER(arg_unit, freep); STATIC_DESTRUCTOR_REGISTER(arg_profile, freep); +STATIC_DESTRUCTOR_REGISTER(arg_image_policy, image_policy_freep); int acquire_bus(sd_bus **bus, bool *use_full_bus) { int r; @@ -268,6 +270,7 @@ static int help(int argc, char *argv[], void *userdata) { " -q --quiet Do not emit hints\n" " --root=PATH Operate on an alternate filesystem root\n" " --image=PATH Operate on disk image as filesystem root\n" + " --image-policy=POLICY Specify disk image dissection policy\n" "\nSee the %s for details.\n", program_invocation_short_name, ansi_highlight(), @@ -307,6 +310,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_PROFILE, ARG_TABLE, ARG_NO_LEGEND, + ARG_IMAGE_POLICY, }; static const struct option options[] = { @@ -339,6 +343,7 @@ static int parse_argv(int argc, char *argv[]) { { "profile", required_argument, NULL, ARG_PROFILE }, { "table", optional_argument, NULL, ARG_TABLE }, { "no-legend", optional_argument, NULL, ARG_NO_LEGEND }, + { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY }, {} }; @@ -522,6 +527,18 @@ static int parse_argv(int argc, char *argv[]) { arg_legend = false; 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; @@ -643,6 +660,7 @@ static int run(int argc, char *argv[]) { r = mount_image_privately_interactively( arg_image, + arg_image_policy, DISSECT_IMAGE_GENERIC_ROOT | DISSECT_IMAGE_RELAX_VAR_CHECK | DISSECT_IMAGE_READ_ONLY, diff --git a/src/analyze/analyze.h b/src/analyze/analyze.h index 2f623e3201..84575cd9a9 100644 --- a/src/analyze/analyze.h +++ b/src/analyze/analyze.h @@ -38,6 +38,7 @@ extern bool arg_quiet; extern char *arg_profile; extern bool arg_legend; extern bool arg_table; +extern ImagePolicy *arg_image_policy; int acquire_bus(sd_bus **bus, bool *use_full_bus); -- cgit v1.2.1 From a62e12dad12434aeecccd58e78bcae4cf1b0d730 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 6 Dec 2022 21:15:06 +0100 Subject: analyze: add 'image-policy' tool for analyzing image dissection policies --- src/analyze/analyze-image-policy.c | 152 +++++++++++++++++++++++++++++++++++++ src/analyze/analyze-image-policy.h | 3 + src/analyze/analyze.c | 2 + src/analyze/meson.build | 1 + 4 files changed, 158 insertions(+) create mode 100644 src/analyze/analyze-image-policy.c create mode 100644 src/analyze/analyze-image-policy.h (limited to 'src/analyze') diff --git a/src/analyze/analyze-image-policy.c b/src/analyze/analyze-image-policy.c new file mode 100644 index 0000000000..e670fe5c4d --- /dev/null +++ b/src/analyze/analyze-image-policy.c @@ -0,0 +1,152 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "analyze-image-policy.h" +#include "analyze.h" +#include "format-table.h" +#include "terminal-util.h" + +static int table_add_designator_line(Table *table, PartitionDesignator d, PartitionPolicyFlags f) { + _cleanup_free_ char *q = NULL; + const char *color; + int r; + + assert(table); + assert(f >= 0); + + if (partition_policy_flags_to_string(f & _PARTITION_POLICY_USE_MASK, /* simplify= */ true, &q) < 0) + return log_oom(); + + color = (f & _PARTITION_POLICY_USE_MASK) == PARTITION_POLICY_IGNORE ? ansi_grey() : + ((f & (PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ABSENT)) == + (PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ABSENT)) ? ansi_highlight_yellow() : + (f & _PARTITION_POLICY_USE_MASK) == PARTITION_POLICY_ABSENT ? ansi_highlight_red() : + !(f & PARTITION_POLICY_UNPROTECTED) ? ansi_highlight_green() : NULL; + + if (d < 0) + r = table_add_many(table, + TABLE_STRING, "default", + TABLE_SET_COLOR, ansi_highlight_green(), + TABLE_STRING, q, + TABLE_SET_COLOR, color); + else + r = table_add_many(table, + TABLE_STRING, partition_designator_to_string(d), + TABLE_SET_COLOR, ansi_normal(), + TABLE_STRING, q, + TABLE_SET_COLOR, color); + if (r < 0) + return table_log_add_error(r); + + switch (f & _PARTITION_POLICY_READ_ONLY_MASK) { + + case PARTITION_POLICY_READ_ONLY_ON: + r = table_add_many(table, TABLE_BOOLEAN, true); + break; + + case PARTITION_POLICY_READ_ONLY_OFF: + r = table_add_many(table, TABLE_BOOLEAN, false); + break; + + default: + r = table_add_many(table, TABLE_EMPTY); + break; + } + if (r < 0) + return table_log_add_error(r); + + switch (f & _PARTITION_POLICY_GROWFS_MASK) { + + case PARTITION_POLICY_GROWFS_ON: + r = table_add_many(table, TABLE_BOOLEAN, true); + break; + + case PARTITION_POLICY_GROWFS_OFF: + r = table_add_many(table, TABLE_BOOLEAN, false); + break; + + default: + r = table_add_many(table, TABLE_EMPTY); + break; + } + + if (r < 0) + return table_log_add_error(r); + + return 0; +} + +int verb_image_policy(int argc, char *argv[], void *userdata) { + int r; + + for (int i = 1; i < argc; i++) { + _cleanup_(table_unrefp) Table *table = NULL; + _cleanup_(image_policy_freep) ImagePolicy *pbuf = NULL; + _cleanup_free_ char *as_string = NULL, *as_string_simplified = NULL; + const ImagePolicy *p; + + /* NB: The magic '@' strings are not officially documented for now, since we might change + * around defaults (and in particular where precisely to reuse policy). We should document + * them once the dust has settled a bit. For now it's just useful for debugging and + * introspect our own defaults without guaranteeing API safety. */ + if (streq(argv[i], "@sysext")) + p = &image_policy_sysext; + else if (streq(argv[i], "@container")) + p = &image_policy_container; + else if (streq(argv[i], "@service")) + p = &image_policy_service; + else if (streq(argv[i], "@host")) + p = &image_policy_host; + else { + r = image_policy_from_string(argv[i], &pbuf); + if (r < 0) + return log_error_errno(r, "Failed to parse image policy '%s': %m", argv[i]); + + p = pbuf; + } + + r = image_policy_to_string(p, /* simplify= */ false, &as_string); + if (r < 0) + return log_error_errno(r, "Failed to format policy '%s' as string: %m", argv[i]); + + r = image_policy_to_string(p, /* simplify= */ true, &as_string_simplified); + if (r < 0) + return log_error_errno(r, "Failed to format policy '%s' as string: %m", argv[i]); + + pager_open(arg_pager_flags); + + if (streq(as_string, as_string_simplified)) + printf("Analyzing policy: %s%s%s\n", ansi_highlight_magenta_underline(), as_string, ansi_normal()); + else + printf("Analyzing policy: %s%s%s\n" + " Long form: %s%s%s\n", + ansi_highlight(), as_string_simplified, ansi_normal(), + ansi_grey(), as_string, ansi_normal()); + + table = table_new("partition", "mode", "read-only", "growfs"); + if (!table) + return log_oom(); + + (void) table_set_ersatz_string(table, TABLE_ERSATZ_DASH); + + for (PartitionDesignator d = 0; d < _PARTITION_DESIGNATOR_MAX; d++) { + PartitionPolicyFlags f = image_policy_get_exhaustively(p, d); + assert(f >= 0); + + r = table_add_designator_line(table, d, f); + if (r < 0) + return r; + } + + r = table_add_designator_line(table, _PARTITION_DESIGNATOR_INVALID, image_policy_default(p)); + if (r < 0) + return r; + + putc('\n', stdout); + + r = table_print(table, NULL); + if (r < 0) + return r; + } + + return EXIT_SUCCESS; +} diff --git a/src/analyze/analyze-image-policy.h b/src/analyze/analyze-image-policy.h new file mode 100644 index 0000000000..fa08447822 --- /dev/null +++ b/src/analyze/analyze-image-policy.h @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +int verb_image_policy(int argc, char *argv[], void *userdata); diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c index 8bc533b20d..ddc71b98b0 100644 --- a/src/analyze/analyze.c +++ b/src/analyze/analyze.c @@ -39,6 +39,7 @@ #include "analyze-unit-files.h" #include "analyze-unit-paths.h" #include "analyze-verify.h" +#include "analyze-image-policy.h" #include "build.h" #include "bus-error.h" #include "bus-locator.h" @@ -640,6 +641,7 @@ static int run(int argc, char *argv[]) { { "inspect-elf", 2, VERB_ANY, 0, verb_elf_inspection }, { "malloc", VERB_ANY, VERB_ANY, 0, verb_malloc }, { "fdstore", 2, VERB_ANY, 0, verb_fdstore }, + { "image-policy", 2, 2, 0, verb_image_policy }, {} }; diff --git a/src/analyze/meson.build b/src/analyze/meson.build index 695089a0be..c50c35f09f 100644 --- a/src/analyze/meson.build +++ b/src/analyze/meson.build @@ -13,6 +13,7 @@ systemd_analyze_sources = files( 'analyze-exit-status.c', 'analyze-fdstore.c', 'analyze-filesystems.c', + 'analyze-image-policy.c', 'analyze-inspect-elf.c', 'analyze-log-control.c', 'analyze-malloc.c', -- cgit v1.2.1 From a594288d79f27147d95662927aa67c0567deb6cc Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 13 Dec 2022 16:27:48 +0100 Subject: sysext: default to a stricter image policy when reading /.extra/sysext/ DDIs --- src/analyze/analyze-image-policy.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/analyze') diff --git a/src/analyze/analyze-image-policy.c b/src/analyze/analyze-image-policy.c index e670fe5c4d..026216629c 100644 --- a/src/analyze/analyze-image-policy.c +++ b/src/analyze/analyze-image-policy.c @@ -90,6 +90,8 @@ int verb_image_policy(int argc, char *argv[], void *userdata) { * introspect our own defaults without guaranteeing API safety. */ if (streq(argv[i], "@sysext")) p = &image_policy_sysext; + else if (streq(argv[i], "@sysext-strict")) + p = &image_policy_sysext_strict; else if (streq(argv[i], "@container")) p = &image_policy_container; else if (streq(argv[i], "@service")) -- cgit v1.2.1