Nella citazione in data ven 09 ago 2013 04:39:35 CEST, Andrey Borzenkov
ha scritto:
>
> This condition sounds strange. Should it not be " == ZEC_MAGIC"?
>

Obviously you're right! Thanks for catching this!
I've attached the updated patch.
Massimo Maggi
From 7270d3fe49fbaf168897f84b0cc75cd4450264f6 Mon Sep 17 00:00:00 2001
From: Massimo Maggi <m...@massimo-maggi.eu>
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<m...@massimo-maggi.eu>
---
 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..54d2612 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

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to