From: Thomas Weißschuh Date: Sat, 10 Sep 2022 09:14:31 +0000 (+0200) Subject: libblkid: btrfs: add checksum support X-Git-Tag: v2.39-rc1~526^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a7135957848d2eba1132cf564833bd21adbafb40;p=thirdparty%2Futil-linux.git libblkid: btrfs: add checksum support Signed-off-by: Thomas Weißschuh --- diff --git a/libblkid/src/superblocks/btrfs.c b/libblkid/src/superblocks/btrfs.c index 6e3fb71e40..2493418086 100644 --- a/libblkid/src/superblocks/btrfs.c +++ b/libblkid/src/superblocks/btrfs.c @@ -18,9 +18,15 @@ #endif #include "superblocks.h" +#include "crc32c.h" + +union btrfs_super_block_csum { + uint8_t bytes[32]; + uint32_t crc32c; +}; struct btrfs_super_block { - uint8_t csum[32]; + union btrfs_super_block_csum csum; uint8_t fsid[16]; uint64_t bytenr; uint64_t flags; @@ -64,6 +70,7 @@ struct btrfs_super_block { uint8_t fsid[16]; } __attribute__ ((__packed__)) dev_item; uint8_t label[256]; + uint8_t padding[3541]; /* pad to BTRFS_SUPER_INFO_SIZE for csum calculation */ } __attribute__ ((__packed__)); #define BTRFS_SUPER_INFO_SIZE 4096 @@ -202,6 +209,21 @@ out: } #endif +static int btrfs_verify_csum(blkid_probe pr, const struct btrfs_super_block *bfs) +{ + int csum_type = le16_to_cpu(bfs->csum_type); + if (csum_type != 0) { + DBG(LOWPROBE, ul_debug("(btrfs) unknown checksum type %d, skipping validation", + csum_type)); + return 1; + } + uint32_t crc = crc32c(~0L, (char *) bfs + sizeof(bfs->csum), + sizeof(*bfs) - sizeof(bfs->csum) + ); + crc ^= ~0L; + return blkid_probe_verify_csum(pr, crc, le32_to_cpu(bfs->csum.crc32c)); +} + static int probe_btrfs(blkid_probe pr, const struct blkid_idmag *mag) { struct btrfs_super_block *bfs; @@ -227,6 +249,9 @@ static int probe_btrfs(blkid_probe pr, const struct blkid_idmag *mag) if (!bfs) return errno ? -errno : 1; + if (!btrfs_verify_csum(pr, bfs)) + return 1; + if (*bfs->label) blkid_probe_set_label(pr, (unsigned char *) bfs->label,