mirror of
https://github.com/Dasharo/systemd.git
synced 2026-03-06 15:02:31 -08:00
analyze: add 'image-policy' tool for analyzing image dissection policies
This commit is contained in:
152
src/analyze/analyze-image-policy.c
Normal file
152
src/analyze/analyze-image-policy.c
Normal file
@@ -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;
|
||||
}
|
||||
3
src/analyze/analyze-image-policy.h
Normal file
3
src/analyze/analyze-image-policy.h
Normal file
@@ -0,0 +1,3 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
int verb_image_policy(int argc, char *argv[], void *userdata);
|
||||
@@ -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 },
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -816,6 +816,18 @@ name=$(echo "$output" | awk '{ print $4 }')
|
||||
check deny yes /run/systemd/transient/"$name"
|
||||
check deny no "$name"
|
||||
|
||||
# Let's also test the "image-policy" verb
|
||||
|
||||
systemd-analyze image-policy '*' 2>&1 | grep -q -F "Long form: =verity+signed+encrypted+unprotected+unused+absent"
|
||||
systemd-analyze image-policy '-' 2>&1 | grep -q -F "Long form: =unused+absent"
|
||||
systemd-analyze image-policy 'home=encrypted:usr=verity' 2>&1 | grep -q -F "Long form: usr=verity:home=encrypted:=unused+absent"
|
||||
systemd-analyze image-policy 'home=encrypted:usr=verity' 2>&1 | grep -q -e '^home \+encrypted \+'
|
||||
systemd-analyze image-policy 'home=encrypted:usr=verity' 2>&1 | grep -q -e '^usr \+verity \+'
|
||||
systemd-analyze image-policy 'home=encrypted:usr=verity' 2>&1 | grep -q -e '^root \+ignore \+'
|
||||
systemd-analyze image-policy 'home=encrypted:usr=verity' 2>&1 | grep -q -e '^usr-verity \+unprotected \+'
|
||||
|
||||
(! systemd-analyze image-policy 'doedel' )
|
||||
|
||||
systemd-analyze log-level info
|
||||
|
||||
echo OK >/testok
|
||||
|
||||
Reference in New Issue
Block a user