From: Michael A Cassaniti Date: Fri, 11 Aug 2023 12:05:45 +0000 (+1000) Subject: sysupdate: Use sector size for partition size calculations X-Git-Tag: v255-rc1~725 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=eeee4861594f2827fb80d748535489f46ec036a4;p=thirdparty%2Fsystemd.git sysupdate: Use sector size for partition size calculations --- diff --git a/src/sysupdate/sysupdate-partition.c b/src/sysupdate/sysupdate-partition.c index fa4453d6651..6f8e0722779 100644 --- a/src/sysupdate/sysupdate-partition.c +++ b/src/sysupdate/sysupdate-partition.c @@ -28,6 +28,7 @@ int read_partition_info( const char *label; struct fdisk_partition *p; uint64_t start, size, flags; + unsigned long ssz; sd_id128_t ptid, id; GptPartitionType type; size_t partno; @@ -54,12 +55,13 @@ int read_partition_info( partno = fdisk_partition_get_partno(p); start = fdisk_partition_get_start(p); - assert(start <= UINT64_MAX / 512U); - start *= 512U; + ssz = fdisk_get_sector_size(c); + assert(start <= UINT64_MAX / ssz); + start *= ssz; size = fdisk_partition_get_size(p); - assert(size <= UINT64_MAX / 512U); - size *= 512U; + assert(size <= UINT64_MAX / ssz); + size *= ssz; label = fdisk_partition_get_name(p); if (!label) diff --git a/test/units/testsuite-72.sh b/test/units/testsuite-72.sh index 36c9712a095..e428e902b1a 100755 --- a/test/units/testsuite-72.sh +++ b/test/units/testsuite-72.sh @@ -6,22 +6,113 @@ set -eux set -o pipefail SYSUPDATE=/lib/systemd/systemd-sysupdate +SECTOR_SIZES="512 4096" +BACKING_FILE=/var/tmp/72-joined.raw +export SYSTEMD_ESP_PATH=/var/tmp/72-esp +export SYSTEMD_XBOOTLDR_PATH=/var/tmp/72-xbootldr +export SYSTEMD_PAGER=cat +export SYSTEMD_LOG_LEVEL=debug if ! test -x "$SYSUPDATE"; then echo "no systemd-sysupdate" >/skipped exit 0 fi -export SYSTEMD_PAGER=cat -export SYSTEMD_LOG_LEVEL=debug +# Loopback devices may not be supported. They are used because sfdisk cannot +# change the sector size of a file, and we want to test both 512 and 4096 byte +# sectors. If loopback devices are not supported, we can only test one sector +# size, and the underlying device is likely to have a sector size of 512 bytes. +if ! losetup --find >/dev/null 2>&1; then + echo "No loopback device support" + SECTOR_SIZES="512" +fi -rm -f /var/tmp/72-joined.raw -truncate -s 10M /var/tmp/72-joined.raw +trap cleanup ERR +cleanup() { + set +o pipefail + blockdev="$( losetup --list --output NAME,BACK-FILE | grep $BACKING_FILE | cut -d' ' -f1)" + [ -n "$blockdev" ] && losetup --detach "$blockdev" + rm -f "$BACKING_FILE" + rm -rf /var/tmp/72-{dirs,defs,source,xbootldr,esp} + rm -f /testok +} + +new_version() { + # Inputs: + # $1: sector size + # $2: version + + # Create a pair of random partition payloads, and compress one + dd if=/dev/urandom of="/var/tmp/72-source/part1-$2.raw" bs="$1" count=2048 + dd if=/dev/urandom of="/var/tmp/72-source/part2-$2.raw" bs="$1" count=2048 + gzip -k -f "/var/tmp/72-source/part2-$2.raw" + + # Create a random "UKI" payload + echo $RANDOM >"/var/tmp/72-source/uki-$2.efi" + + # Create tarball of a directory + mkdir -p "/var/tmp/72-source/dir-$2" + echo $RANDOM >"/var/tmp/72-source/dir-$2/foo.txt" + echo $RANDOM >"/var/tmp/72-source/dir-$2/bar.txt" + tar --numeric-owner -C "/var/tmp/72-source/dir-$2/" -czf "/var/tmp/72-source/dir-$2.tar.gz" . + + ( cd /var/tmp/72-source/ && sha256sum uki* part* dir-*.tar.gz >SHA256SUMS ) +} -sfdisk /var/tmp/72-joined.raw </dev/null 2>&1; then + # shellcheck disable=SC2086 + blockdev="$(losetup --find --show --sector-size $sector_size $BACKING_FILE)" + else + blockdev="$BACKING_FILE" + fi + + sfdisk "$blockdev" </var/tmp/72-defs/01-first.conf <<"EOF" + cat >/var/tmp/72-defs/01-first.conf </var/tmp/72-defs/02-second.conf <<"EOF" + cat >/var/tmp/72-defs/02-second.conf </var/tmp/72-defs/03-third.conf <<"EOF" + cat >/var/tmp/72-defs/03-third.conf </var/tmp/72-defs/04-fourth.conf <<"EOF" + cat >/var/tmp/72-defs/04-fourth.conf <"/var/tmp/72-source/uki-$1.efi" - - # Create tarball of a directory - mkdir -p "/var/tmp/72-source/dir-$1" - echo $RANDOM >"/var/tmp/72-source/dir-$1/foo.txt" - echo $RANDOM >"/var/tmp/72-source/dir-$1/bar.txt" - tar --numeric-owner -C "/var/tmp/72-source/dir-$1/" -czf "/var/tmp/72-source/dir-$1.tar.gz" . - - ( cd /var/tmp/72-source/ && sha256sum uki* part* dir-*.tar.gz >SHA256SUMS ) -} - -update_now() { - # Update to newest version. First there should be an update ready, then we - # do the update, and then there should not be any ready anymore - - "$SYSUPDATE" --definitions=/var/tmp/72-defs --verify=no check-new - "$SYSUPDATE" --definitions=/var/tmp/72-defs --verify=no update - ( ! "$SYSUPDATE" --definitions=/var/tmp/72-defs --verify=no check-new ) -} - -verify_version() { - # Expects: version ID + sector offset of both partitions to compare - - # Check the partitions - dd if=/var/tmp/72-joined.raw bs=1024 skip="$2" count=1024 | cmp "/var/tmp/72-source/part1-$1.raw" - dd if=/var/tmp/72-joined.raw bs=1024 skip="$3" count=1024 | cmp "/var/tmp/72-source/part2-$1.raw" - - # Check the UKI - cmp "/var/tmp/72-source/uki-$1.efi" "/var/tmp/72-xbootldr/EFI/Linux/uki_$1+3-0.efi" - test -z "$(ls -A /var/tmp/72-esp/EFI/Linux)" - - # Check the directories - cmp "/var/tmp/72-source/dir-$1/foo.txt" /var/tmp/72-dirs/current/foo.txt - cmp "/var/tmp/72-source/dir-$1/bar.txt" /var/tmp/72-dirs/current/bar.txt -} - -# Install initial version and verify -new_version v1 -update_now -verify_version v1 1024 3072 - -# Create second version, update and verify that it is added -new_version v2 -update_now -verify_version v2 2048 4096 - -# Create third version, update and verify it replaced the first version -new_version v3 -update_now -verify_version v3 1024 3072 -test ! -f "/var/tmp/72-xbootldr/EFI/Linux/uki_v1+3-0.efi" - -# Create fourth version, and update through a file:// URL. This should be -# almost as good as testing HTTP, but is simpler for us to set up. file:// is -# abstracted in curl for us, and since our main goal is to test our own code -# (and not curl) this test should be quite good even if not comprehensive. This -# will test the SHA256SUMS logic at least (we turn off GPG validation though, -# see above) -new_version v4 - -cat >/var/tmp/72-defs/02-second.conf <<"EOF" + rm -rf /var/tmp/72-esp /var/tmp/72-xbootldr + mkdir -p /var/tmp/72-esp/EFI/Linux /var/tmp/72-xbootldr/EFI/Linux + + rm -rf /var/tmp/72-source + mkdir -p /var/tmp/72-source + + # Install initial version and verify + new_version "$sector_size" v1 + update_now + verify_version "$blockdev" "$sector_size" v1 1 3 + + # Create second version, update and verify that it is added + new_version "$sector_size" v2 + update_now + verify_version "$blockdev" "$sector_size" v2 2 4 + + # Create third version, update and verify it replaced the first version + new_version "$sector_size" v3 + update_now + verify_version "$blockdev" "$sector_size" v3 1 3 + test ! -f "/var/tmp/72-xbootldr/EFI/Linux/uki_v1+3-0.efi" + + # Create fourth version, and update through a file:// URL. This should be + # almost as good as testing HTTP, but is simpler for us to set up. file:// is + # abstracted in curl for us, and since our main goal is to test our own code + # (and not curl) this test should be quite good even if not comprehensive. This + # will test the SHA256SUMS logic at least (we turn off GPG validation though, + # see above) + new_version "$sector_size" v4 + + cat >/var/tmp/72-defs/02-second.conf </var/tmp/72-defs/03-third.conf <<"EOF" + cat >/var/tmp/72-defs/03-third.conf <