From: Jeremy Linton Date: Fri, 14 Apr 2023 21:25:28 +0000 (-0500) Subject: libblkid: Compute CRC with sb_crc zeroed X-Git-Tag: v2.39-rc3~26^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f8017377281659c0d4ad405b75baf1cd7788515b;p=thirdparty%2Futil-linux.git libblkid: Compute CRC with sb_crc zeroed The Linux kernel computes the sb_crc by crcing the superblock with the CRC field set to 0. The code is trying to avoid doing this in three separate CRC calls like the kernel performs by simply zeroing the field and making a single call. Except that the passed copy "ondisk" isn't the same as the returned copy "csummed" so the zeroing goes into the wrong buffer. Meaning that the CRC is computed incorrectly. This results in blkid returning: /dev/sda4: PARTUUID="2f162043-63c2-d145-869b-e53f9db57476" rather than: /dev/sda4: UUID="45b931b7-592a-46dc-9c33-d38d5901ec29" BLOCK_SIZE="4096" TYPE="xfs" PARTUUID="2f162043-63c2-d145-869b-e53f9db57476" Which can result in lots of failures including boot failures if XFS modules aren't placed into the initrd, or scripts/etc cannot determine the fs UUID. Signed-off-by: Jeremy Linton --- diff --git a/libblkid/src/superblocks/xfs.c b/libblkid/src/superblocks/xfs.c index 4f80c5c968..6ab47ef1e4 100644 --- a/libblkid/src/superblocks/xfs.c +++ b/libblkid/src/superblocks/xfs.c @@ -207,6 +207,7 @@ static int xfs_verify_sb(struct xfs_super_block *ondisk, blkid_probe pr, if ((sbp->sb_versionnum & 0x0f) == 5) { uint32_t expected, crc; unsigned char *csummed; + int crc_offset = offsetof(struct xfs_super_block, sb_crc); if (!(sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT)) return 0; @@ -218,8 +219,8 @@ static int xfs_verify_sb(struct xfs_super_block *ondisk, blkid_probe pr, if (!csummed) return 0; - ondisk->sb_crc = 0; - crc = crc32c(~0LL, csummed, sbp->sb_sectsize); + crc = ul_crc32c_exclude_offset(~0LL, csummed, sbp->sb_sectsize, + crc_offset, sizeof(sbp->sb_crc)); crc = bswap_32(crc ^ ~0LL); if (!blkid_probe_verify_csum(pr, crc, expected))