mirror of
https://github.com/systemd/systemd
synced 2024-09-06 16:56:43 +00:00
repart: Add verity configuration section and options
This commit is contained in:
parent
f19659b91f
commit
c380047bf4
|
@ -576,6 +576,24 @@
|
|||
<varname>Verity=</varname>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>VerityDataBlockSizeBytes=</varname></term>
|
||||
|
||||
<listitem><para>Configures the data block size of the generated verity hash partition. Must be between 512 and
|
||||
4096 bytes and must be a power of 2. Defaults to the sector size if configured explicitly, or the underlying
|
||||
block device sector size, or 4K if systemd-repart is not operating on a block device.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>VerityHashBlockSizeBytes=</varname></term>
|
||||
|
||||
<listitem><para>Configures the hash block size of the generated verity hash partition. Must be between 512 and
|
||||
4096 bytes and must be a power of 2. Defaults to the sector size if configured explicitly, or the underlying
|
||||
block device sector size, or 4K if systemd-repart is not operating on a block device.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>FactoryReset=</varname></term>
|
||||
|
||||
|
@ -831,6 +849,9 @@ VerityMatchKey=root
|
|||
Type=root-verity
|
||||
Verity=hash
|
||||
VerityMatchKey=root
|
||||
# Explicitly set the hash and data block size to 4K
|
||||
VerityDataBlockSizeBytes=4096
|
||||
VerityHashBlockSizeBytes=4096
|
||||
</programlisting></para>
|
||||
</example>
|
||||
|
||||
|
|
|
@ -252,6 +252,8 @@ typedef struct Partition {
|
|||
VerityMode verity;
|
||||
char *verity_match_key;
|
||||
MinimizeMode minimize;
|
||||
uint64_t verity_data_block_size;
|
||||
uint64_t verity_hash_block_size;
|
||||
|
||||
uint64_t gpt_flags;
|
||||
int no_auto;
|
||||
|
@ -363,6 +365,8 @@ static Partition *partition_new(void) {
|
|||
.no_auto = -1,
|
||||
.read_only = -1,
|
||||
.growfs = -1,
|
||||
.verity_data_block_size = UINT64_MAX,
|
||||
.verity_hash_block_size = UINT64_MAX,
|
||||
};
|
||||
|
||||
return p;
|
||||
|
@ -1322,6 +1326,40 @@ static int config_parse_size4096(
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int config_parse_block_size(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
uint64_t *blksz = ASSERT_PTR(data), parsed;
|
||||
int r;
|
||||
|
||||
assert(rvalue);
|
||||
|
||||
r = parse_size(rvalue, 1024, &parsed);
|
||||
if (r < 0)
|
||||
return log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to parse size value: %s", rvalue);
|
||||
|
||||
if (parsed < 512 || parsed > 4096)
|
||||
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL),
|
||||
"Value not between 512 and 4096: %s", rvalue);
|
||||
|
||||
if (!ISPOWEROF2(parsed))
|
||||
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL),
|
||||
"Value not a power of 2: %s", rvalue);
|
||||
|
||||
*blksz = parsed;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int config_parse_fstype(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
|
@ -1616,33 +1654,35 @@ static DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(config_parse_minimize, minimize_mod
|
|||
static int partition_read_definition(Partition *p, const char *path, const char *const *conf_file_dirs) {
|
||||
|
||||
ConfigTableItem table[] = {
|
||||
{ "Partition", "Type", config_parse_type, 0, &p->type },
|
||||
{ "Partition", "Label", config_parse_label, 0, &p->new_label },
|
||||
{ "Partition", "UUID", config_parse_uuid, 0, p },
|
||||
{ "Partition", "Priority", config_parse_int32, 0, &p->priority },
|
||||
{ "Partition", "Weight", config_parse_weight, 0, &p->weight },
|
||||
{ "Partition", "PaddingWeight", config_parse_weight, 0, &p->padding_weight },
|
||||
{ "Partition", "SizeMinBytes", config_parse_size4096, 1, &p->size_min },
|
||||
{ "Partition", "SizeMaxBytes", config_parse_size4096, -1, &p->size_max },
|
||||
{ "Partition", "PaddingMinBytes", config_parse_size4096, 1, &p->padding_min },
|
||||
{ "Partition", "PaddingMaxBytes", config_parse_size4096, -1, &p->padding_max },
|
||||
{ "Partition", "FactoryReset", config_parse_bool, 0, &p->factory_reset },
|
||||
{ "Partition", "CopyBlocks", config_parse_copy_blocks, 0, p },
|
||||
{ "Partition", "Format", config_parse_fstype, 0, &p->format },
|
||||
{ "Partition", "CopyFiles", config_parse_copy_files, 0, &p->copy_files },
|
||||
{ "Partition", "ExcludeFiles", config_parse_exclude_files, 0, &p->exclude_files_source },
|
||||
{ "Partition", "ExcludeFilesTarget", config_parse_exclude_files, 0, &p->exclude_files_target },
|
||||
{ "Partition", "MakeDirectories", config_parse_make_dirs, 0, &p->make_directories },
|
||||
{ "Partition", "Encrypt", config_parse_encrypt, 0, &p->encrypt },
|
||||
{ "Partition", "Verity", config_parse_verity, 0, &p->verity },
|
||||
{ "Partition", "VerityMatchKey", config_parse_string, 0, &p->verity_match_key },
|
||||
{ "Partition", "Flags", config_parse_gpt_flags, 0, &p->gpt_flags },
|
||||
{ "Partition", "ReadOnly", config_parse_tristate, 0, &p->read_only },
|
||||
{ "Partition", "NoAuto", config_parse_tristate, 0, &p->no_auto },
|
||||
{ "Partition", "GrowFileSystem", config_parse_tristate, 0, &p->growfs },
|
||||
{ "Partition", "SplitName", config_parse_string, 0, &p->split_name_format },
|
||||
{ "Partition", "Minimize", config_parse_minimize, 0, &p->minimize },
|
||||
{ "Partition", "Subvolumes", config_parse_make_dirs, 0, &p->subvolumes },
|
||||
{ "Partition", "Type", config_parse_type, 0, &p->type },
|
||||
{ "Partition", "Label", config_parse_label, 0, &p->new_label },
|
||||
{ "Partition", "UUID", config_parse_uuid, 0, p },
|
||||
{ "Partition", "Priority", config_parse_int32, 0, &p->priority },
|
||||
{ "Partition", "Weight", config_parse_weight, 0, &p->weight },
|
||||
{ "Partition", "PaddingWeight", config_parse_weight, 0, &p->padding_weight },
|
||||
{ "Partition", "SizeMinBytes", config_parse_size4096, 1, &p->size_min },
|
||||
{ "Partition", "SizeMaxBytes", config_parse_size4096, -1, &p->size_max },
|
||||
{ "Partition", "PaddingMinBytes", config_parse_size4096, 1, &p->padding_min },
|
||||
{ "Partition", "PaddingMaxBytes", config_parse_size4096, -1, &p->padding_max },
|
||||
{ "Partition", "FactoryReset", config_parse_bool, 0, &p->factory_reset },
|
||||
{ "Partition", "CopyBlocks", config_parse_copy_blocks, 0, p },
|
||||
{ "Partition", "Format", config_parse_fstype, 0, &p->format },
|
||||
{ "Partition", "CopyFiles", config_parse_copy_files, 0, &p->copy_files },
|
||||
{ "Partition", "ExcludeFiles", config_parse_exclude_files, 0, &p->exclude_files_source },
|
||||
{ "Partition", "ExcludeFilesTarget", config_parse_exclude_files, 0, &p->exclude_files_target },
|
||||
{ "Partition", "MakeDirectories", config_parse_make_dirs, 0, &p->make_directories },
|
||||
{ "Partition", "Encrypt", config_parse_encrypt, 0, &p->encrypt },
|
||||
{ "Partition", "Verity", config_parse_verity, 0, &p->verity },
|
||||
{ "Partition", "VerityMatchKey", config_parse_string, 0, &p->verity_match_key },
|
||||
{ "Partition", "Flags", config_parse_gpt_flags, 0, &p->gpt_flags },
|
||||
{ "Partition", "ReadOnly", config_parse_tristate, 0, &p->read_only },
|
||||
{ "Partition", "NoAuto", config_parse_tristate, 0, &p->no_auto },
|
||||
{ "Partition", "GrowFileSystem", config_parse_tristate, 0, &p->growfs },
|
||||
{ "Partition", "SplitName", config_parse_string, 0, &p->split_name_format },
|
||||
{ "Partition", "Minimize", config_parse_minimize, 0, &p->minimize },
|
||||
{ "Partition", "Subvolumes", config_parse_make_dirs, 0, &p->subvolumes },
|
||||
{ "Partition", "VerityDataBlockSizeBytes", config_parse_block_size, 0, &p->verity_data_block_size },
|
||||
{ "Partition", "VerityHashBlockSizeBytes", config_parse_block_size, 0, &p->verity_hash_block_size },
|
||||
{}
|
||||
};
|
||||
int r;
|
||||
|
@ -3938,6 +3978,11 @@ static int partition_format_verity_hash(
|
|||
node = partition_target_path(t);
|
||||
}
|
||||
|
||||
if (p->verity_data_block_size == UINT64_MAX)
|
||||
p->verity_data_block_size = context->fs_sector_size;
|
||||
if (p->verity_hash_block_size == UINT64_MAX)
|
||||
p->verity_hash_block_size = context->fs_sector_size;
|
||||
|
||||
r = sym_crypt_init(&cd, node);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to allocate libcryptsetup context for %s: %m", node);
|
||||
|
@ -3951,8 +3996,8 @@ static int partition_format_verity_hash(
|
|||
.flags = CRYPT_VERITY_CREATE_HASH,
|
||||
.hash_name = "sha256",
|
||||
.hash_type = 1,
|
||||
.data_block_size = context->fs_sector_size,
|
||||
.hash_block_size = context->fs_sector_size,
|
||||
.data_block_size = p->verity_data_block_size,
|
||||
.hash_block_size = p->verity_hash_block_size,
|
||||
.salt_size = sizeof(p->verity_salt),
|
||||
.salt = (const char*)p->verity_salt,
|
||||
});
|
||||
|
|
|
@ -16,6 +16,7 @@ test_append_files() {
|
|||
instmods dm_verity =md
|
||||
instmods erofs
|
||||
generate_module_dependencies
|
||||
image_install veritysetup
|
||||
image_install -o mksquashfs
|
||||
image_install -o mkfs.erofs
|
||||
fi
|
||||
|
|
|
@ -99,7 +99,7 @@ testcase_basic() {
|
|||
imgs="$(mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")"
|
||||
# shellcheck disable=SC2064
|
||||
trap "rm -rf '$defs' '$imgs'" RETURN
|
||||
chmod a+rx "$defs"
|
||||
chmod 0755 "$defs"
|
||||
|
||||
echo "*** 1. create an empty image ***"
|
||||
|
||||
|
@ -395,7 +395,7 @@ testcase_dropin() {
|
|||
imgs="$(mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")"
|
||||
# shellcheck disable=SC2064
|
||||
trap "rm -rf '$defs' '$imgs'" RETURN
|
||||
chmod a+rx "$defs"
|
||||
chmod 0755 "$defs"
|
||||
|
||||
tee "$defs/root.conf" <<EOF
|
||||
[Partition]
|
||||
|
@ -455,7 +455,7 @@ testcase_multiple_definitions() {
|
|||
imgs="$(mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")"
|
||||
# shellcheck disable=SC2064
|
||||
trap "rm -rf '$defs' '$imgs'" RETURN
|
||||
chmod a+rx "$defs"
|
||||
chmod 0755 "$defs"
|
||||
|
||||
mkdir -p "$defs/1"
|
||||
tee "$defs/1/root1.conf" <<EOF
|
||||
|
@ -526,7 +526,7 @@ testcase_copy_blocks() {
|
|||
imgs="$(mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")"
|
||||
# shellcheck disable=SC2064
|
||||
trap "rm -rf '$defs' '$imgs'" RETURN
|
||||
chmod a+rx "$defs"
|
||||
chmod 0755 "$defs"
|
||||
|
||||
echo "*** First, create a disk image and verify its in order ***"
|
||||
|
||||
|
@ -610,7 +610,7 @@ testcase_unaligned_partition() {
|
|||
imgs="$(mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")"
|
||||
# shellcheck disable=SC2064
|
||||
trap "rm -rf '$defs' '$imgs'" RETURN
|
||||
chmod a+rx "$defs"
|
||||
chmod 0755 "$defs"
|
||||
|
||||
echo "*** Operate on an image with unaligned partition ***"
|
||||
|
||||
|
@ -647,7 +647,7 @@ testcase_issue_21817() {
|
|||
imgs="$(mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")"
|
||||
# shellcheck disable=SC2064
|
||||
trap "rm -rf '$defs' '$imgs'" RETURN
|
||||
chmod a+rx "$defs"
|
||||
chmod 0755 "$defs"
|
||||
|
||||
echo "*** testcase for #21817 ***"
|
||||
|
||||
|
@ -685,7 +685,7 @@ testcase_issue_24553() {
|
|||
imgs="$(mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")"
|
||||
# shellcheck disable=SC2064
|
||||
trap "rm -rf '$defs' '$imgs'" RETURN
|
||||
chmod a+rx "$defs"
|
||||
chmod 0755 "$defs"
|
||||
|
||||
echo "*** testcase for #24553 ***"
|
||||
|
||||
|
@ -790,7 +790,7 @@ testcase_zero_uuid() {
|
|||
imgs="$(mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")"
|
||||
# shellcheck disable=SC2064
|
||||
trap "rm -rf '$defs' '$imgs'" RETURN
|
||||
chmod a+rx "$defs"
|
||||
chmod 0755 "$defs"
|
||||
|
||||
echo "*** Test image with zero UUID ***"
|
||||
|
||||
|
@ -820,7 +820,7 @@ testcase_verity() {
|
|||
imgs="$(mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")"
|
||||
# shellcheck disable=SC2064
|
||||
trap "rm -rf '$defs' '$imgs'" RETURN
|
||||
chmod a+rx "$defs"
|
||||
chmod 0755 "$defs"
|
||||
|
||||
echo "*** dm-verity ***"
|
||||
|
||||
|
@ -907,6 +907,64 @@ EOF
|
|||
systemd-dissect -U "$imgs/mnt"
|
||||
}
|
||||
|
||||
testcase_verity_explicit_block_size() {
|
||||
local defs imgs loop
|
||||
|
||||
if systemd-detect-virt --quiet --container; then
|
||||
echo "Skipping verity block size tests in container."
|
||||
return
|
||||
fi
|
||||
|
||||
defs="$(mktemp --directory "/tmp/test-repart.defs.XXXXXXXXXX")"
|
||||
imgs="$(mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")"
|
||||
|
||||
# shellcheck disable=SC2064
|
||||
trap "rm -rf '$defs' '$imgs'" RETURN
|
||||
chmod 0755 "$defs"
|
||||
|
||||
echo "*** varying-dm-verity-block-sizes ***"
|
||||
|
||||
tee "$defs/verity-data.conf" <<EOF
|
||||
[Partition]
|
||||
Type=root-${architecture}
|
||||
CopyFiles=${defs}
|
||||
Verity=data
|
||||
VerityMatchKey=root
|
||||
Minimize=guess
|
||||
EOF
|
||||
|
||||
tee "$defs/verity-hash.conf" <<EOF
|
||||
[Partition]
|
||||
Type=root-${architecture}-verity
|
||||
Verity=hash
|
||||
VerityMatchKey=root
|
||||
VerityHashBlockSizeBytes=1024
|
||||
VerityDataBlockSizeBytes=4096
|
||||
Minimize=yes
|
||||
EOF
|
||||
|
||||
systemd-repart --offline="$OFFLINE" \
|
||||
--definitions="$defs" \
|
||||
--seed="$seed" \
|
||||
--dry-run=no \
|
||||
--empty=create \
|
||||
--size=auto \
|
||||
--json=pretty \
|
||||
"$imgs/verity"
|
||||
|
||||
loop="$(losetup --partscan --show --find "$imgs/verity")"
|
||||
|
||||
# Make sure the loopback device gets cleaned up
|
||||
# shellcheck disable=SC2064
|
||||
trap "rm -rf '$defs' '$imgs' ; losetup -d '$loop'" RETURN ERR
|
||||
|
||||
udevadm wait --timeout 60 --settle "${loop:?}"
|
||||
|
||||
# Check that the verity block sizes are as expected
|
||||
veritysetup dump "${loop}p2" | grep 'Data block size:' | grep -q '4096'
|
||||
veritysetup dump "${loop}p2" | grep 'Hash block size:' | grep -q '1024'
|
||||
}
|
||||
|
||||
testcase_exclude_files() {
|
||||
local defs imgs root output
|
||||
|
||||
|
@ -915,7 +973,7 @@ testcase_exclude_files() {
|
|||
root="$(mktemp --directory "/var/tmp/test-repart.root.XXXXXXXXXX")"
|
||||
# shellcheck disable=SC2064
|
||||
trap "rm -rf '$defs' '$imgs' '$root'" RETURN
|
||||
chmod a+rx "$defs"
|
||||
chmod 0755 "$defs"
|
||||
|
||||
echo "*** file exclusion ***"
|
||||
|
||||
|
@ -1070,7 +1128,7 @@ testcase_free_area_calculation() {
|
|||
imgs="$(mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")"
|
||||
# shellcheck disable=SC2064
|
||||
trap "rm -rf '$defs' '$imgs'" RETURN
|
||||
chmod a+rx "$defs"
|
||||
chmod 0755 "$defs"
|
||||
|
||||
# https://github.com/systemd/systemd/issues/28225
|
||||
echo "*** free area calculation ***"
|
||||
|
|
Loading…
Reference in a new issue