repart: trim NUL bytes from verity sig split artifact
The verity signature partition content is a bare JSON object. Repart pads it with zeros to fill the GPT partition. But when splitting out the content as an individual file, the padding remains, so it's not a valid text file. jq started rejecting files with NUL bytes to fix a security issue: https://github.com/jqlang/jq/commit/6374ae0bcdfe33a18eb0ae6db28493b1f34a0a5b Trim the output when writing these files out.
This commit is contained in:
committed by
Zbigniew Jędrzejewski-Szmek
parent
1be5cbd6c1
commit
b54ef83414
+24
-3
@@ -7754,9 +7754,30 @@ static int context_split(Context *context) {
|
||||
if (lseek(fd, p->offset, SEEK_SET) < 0)
|
||||
return log_error_errno(errno, "Failed to seek to partition offset: %m");
|
||||
|
||||
r = copy_bytes(fd, fdt, p->new_size, COPY_REFLINK|COPY_HOLES|COPY_TRUNCATE);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to copy to split partition %s: %m", p->split_path);
|
||||
/* Verity signature partitions contain a JSON object NUL-padded out to the partition
|
||||
* size. The on-disk partition must keep the padding, but the split-out file is a
|
||||
* standalone artifact, so trim the trailing NUL bytes there to avoid tripping jq. */
|
||||
if (partition_designator_is_verity_sig(p->type.designator)) {
|
||||
_cleanup_free_ char *buf = malloc(p->new_size);
|
||||
if (!buf)
|
||||
return log_oom();
|
||||
|
||||
r = loop_read_exact(fd, buf, p->new_size, /* do_poll= */ false);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to read verity signature partition: %m");
|
||||
|
||||
size_t len = strnlen(buf, p->new_size);
|
||||
if (len == 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Verity signature partition is empty");
|
||||
|
||||
r = loop_write(fdt, buf, len);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write to split partition %s: %m", p->split_path);
|
||||
} else {
|
||||
r = copy_bytes(fd, fdt, p->new_size, COPY_REFLINK|COPY_HOLES|COPY_TRUNCATE);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to copy to split partition %s: %m", p->split_path);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -941,6 +941,7 @@ EOF
|
||||
--dry-run=no \
|
||||
--empty=create \
|
||||
--size=auto \
|
||||
--split=yes \
|
||||
--json=pretty \
|
||||
--private-key="$defs/verity.key" \
|
||||
--certificate="$defs/verity.crt" \
|
||||
@@ -953,6 +954,13 @@ EOF
|
||||
assert_eq "$drh" "$hrh"
|
||||
assert_eq "$hrh" "$srh"
|
||||
|
||||
# The split-out verity signature file should be a valid JSON document (i.e. trailing NUL padding
|
||||
# from the on-disk partition must be trimmed when writing the split file).
|
||||
sig_split=$(jq -r ".[] | select(.type == \"root-${architecture}-verity-sig\") | .split_path" <<<"$output")
|
||||
assert_neq "$sig_split" ""
|
||||
assert_neq "$sig_split" "null"
|
||||
jq . "$sig_split" >/dev/null
|
||||
|
||||
# Check that offline signing works and the resulting image is valid
|
||||
|
||||
output=$(systemd-repart --offline="$OFFLINE" \
|
||||
|
||||
Reference in New Issue
Block a user