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;
--dry-run=no \
--empty=create \
--size=auto \
+ --split=yes \
--json=pretty \
--private-key="$defs/verity.key" \
--certificate="$defs/verity.crt" \
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" \