From 82eb1143c7bfef816d3f875041c5d65e7a69c8a5 Mon Sep 17 00:00:00 2001 From: Massimo Maggi Date: Fri, 9 Aug 2013 00:39:33 +0200 Subject: [PATCH] ZFS label detection improvements. In order to not let zfs code mistakenly analyze a block device as a ZFS filesystem when it contains some other filesystem,let's analyze better the label and fail as soon as possible. In details: * Check the magic number of the zio_eck_t in the vdev_phys_t structure, which is the first possible magic number met when analyzing a block device. * Verify the SHA256 checksum of the vdev_phys_t structure, which contains the nvlists that are going to be read later. Signed-off-by: Massimo Maggi --- grub-core/fs/zfs/zfs.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index f4acfd8..ceb4df7 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -969,6 +969,9 @@ check_pool_label (struct grub_zfs_data *data, grub_uint64_t version; int found; grub_err_t err; + int endian; + vdev_phys_t *phys; + zio_cksum_t emptycksum; *inserted = 0; @@ -976,6 +979,28 @@ check_pool_label (struct grub_zfs_data *data, if (err) return err; + phys=(vdev_phys_t*)nvlist; + if( grub_zfs_to_cpu64(phys->vp_zbt.zec_magic, + GRUB_ZFS_LITTLE_ENDIAN) == ZEC_MAGIC) + { + endian = GRUB_ZFS_LITTLE_ENDIAN; + } + else if(grub_zfs_to_cpu64(phys->vp_zbt.zec_magic, + GRUB_ZFS_BIG_ENDIAN) != ZEC_MAGIC) + { + endian = GRUB_ZFS_BIG_ENDIAN; + } + else + { + grub_error (GRUB_ERR_BAD_FS, "bad vdev_phys_t.vp_zbt.zec_magic number"); + return grub_errno; + } + // Now check the integrity of the vdev_phys_t structure though checksum. + ZIO_SET_CHECKSUM(&emptycksum, diskdesc->vdev_phys_sector << 9, 0, 0, 0); + err = zio_checksum_verify (emptycksum, ZIO_CHECKSUM_LABEL, endian, nvlist, VDEV_PHYS_SIZE); + if(err) + return err; + grub_dprintf ("zfs", "check 2 passed\n"); found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_STATE, -- 1.8.2.1