]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sysupdate: reject short manifest hashes
authorLuca Boccassi <luca.boccassi@gmail.com>
Thu, 11 Jun 2026 17:38:59 +0000 (18:38 +0100)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 14 Jun 2026 21:59:24 +0000 (06:59 +0900)
unhexmem_full() ignores whitespace, so a 64-byte manifest digest field
can decode to fewer than 32 bytes. Reject that while parsing instead.

[   83.883087] TEST-72-SYSUPDATE.sh[5995]: systemd-sysupdate: ../src/src/sysupdate/sysupdate-resource.c:581: resource_load_from_web: Assertion `h.iov_len == sizeof(instance->metadata.sha256sum)' failed.

Follow-up for 43cc7a3ef4f6a89946e7ffd6a3112a0c1740b1ef

Assisted-by: kres (claude-opus-4-7)
Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com>
src/sysupdate/sysupdate-resource.c
test/units/TEST-72-SYSUPDATE.sh

index e234b3c914808122acb3f8400d0b613fce3a071d..abc63960df2bb6aaf62a473f8e8102b7097b12c7 100644 (file)
@@ -532,6 +532,11 @@ static int resource_load_from_web(
                 r = unhexmem_full(p, 64, /* secure= */ false, &h.iov_base, &h.iov_len);
                 if (r < 0)
                         return log_error_errno(r, "Failed to parse digest at manifest line %zu, refusing.", line_nr);
+                if (h.iov_len != sizeof_field(InstanceMetadata, sha256sum))
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                               "Manifest hash at line %zu decoded to %zu bytes, refusing.",
+                                               line_nr,
+                                               h.iov_len);
 
                 p += 64, left -= 64;
 
index 0b008271b01c0e2353b33016c1a2a11f3694a006..749af71a0681d567a6653d2c9147c85026b0ccf2 100755 (executable)
@@ -608,4 +608,30 @@ rm "$CONFIGDIR/01-tiny-url.transfer"
 rm "$WORKDIR/source/tiny-v1.bin"
 rm "$WORKDIR/source/SHA256SUMS"
 
+# Check that malformed manifest hashes are rejected without aborting.
+rm -rf "$WORKDIR/malformed-manifest"
+mkdir -p "$WORKDIR/malformed-manifest/definitions" "$WORKDIR/malformed-manifest/source" "$WORKDIR/malformed-manifest/target"
+printf 'payload\n' >"$WORKDIR/malformed-manifest/source/malformed-v1.bin"
+hash_64=0000000000000000000000000000000000000000000000000000000000000000
+printf '%s\t\t *malformed-v1.bin\n' "${hash_64%??}" >"$WORKDIR/malformed-manifest/source/SHA256SUMS"
+cat >"$WORKDIR/malformed-manifest/definitions/01-malformed-hash.transfer" <<EOF
+[Source]
+Type=url-file
+Path=file://$WORKDIR/malformed-manifest/source
+MatchPattern=malformed-@v.bin
+
+[Target]
+Type=regular-file
+Path=$WORKDIR/malformed-manifest/target
+MatchPattern=malformed-@v.bin
+InstancesMax=1
+EOF
+set +e
+"$SYSUPDATE" --definitions="$WORKDIR/malformed-manifest/definitions" --verify=no check-new &>"$WORKDIR/malformed-manifest/check-new.log"
+rc=$?
+set -e
+[[ $rc -ne 0 ]]
+[[ $rc -ne 134 ]]
+grep -F "Manifest hash at line 1 decoded to 31 bytes" "$WORKDIR/malformed-manifest/check-new.log" >/dev/null
+
 touch /testok