]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
* partmap/msdos.c (embed_signatures): New array.
authorColin Watson <cjwatson@ubuntu.com>
Mon, 22 Nov 2010 22:33:55 +0000 (22:33 +0000)
committerColin Watson <cjwatson@ubuntu.com>
Mon, 22 Nov 2010 22:33:55 +0000 (22:33 +0000)
(pc_partition_map_embed): Check for and avoid sectors matching any
of the signatures in embed_signatures.
* util/grub-setup.c (setup): Allow for the embedding area being
split into multiple blocklists.

ChangeLog.embed-sectors [new file with mode: 0644]
grub-core/partmap/msdos.c
util/grub-setup.c

diff --git a/ChangeLog.embed-sectors b/ChangeLog.embed-sectors
new file mode 100644 (file)
index 0000000..e9eade4
--- /dev/null
@@ -0,0 +1,7 @@
+2010-11-22  Colin Watson  <cjwatson@ubuntu.com>
+
+       * partmap/msdos.c (embed_signatures): New array.
+       (pc_partition_map_embed): Check for and avoid sectors matching any
+       of the signatures in embed_signatures.
+       * util/grub-setup.c (setup): Allow for the embedding area being
+       split into multiple blocklists.
index f99e27a6ecf9f36f3dd648c9f720945cc6f1718b..cb836d17110e7a1689b2c461f9afb7ab02afdaae 100644 (file)
 static struct grub_partition_map grub_msdos_partition_map;
 \f
 
+#ifdef GRUB_UTIL
+#include <grub/emu/misc.h>
+
+struct embed_signature
+{
+  const char *name;
+  const char *signature;
+  int signature_len;
+};
+
+/* Signatures of other software that may be using sectors in the embedding
+   area.  */
+struct embed_signature embed_signatures[] =
+  {
+    {
+      .name = "ZISD",
+      .signature = "ZISD",
+      .signature_len = 4
+    },
+    {
+      .name = "FlexNet",
+      .signature = "\xd4\x41\xa0\xf5\x03\x00\x03\x00",
+      .signature_len = 8
+    },
+    {
+      .name = "FlexNet",
+      .signature = "\xd8\x41\xa0\xf5\x02\x00\x02\x00",
+      .signature_len = 8
+    },
+    {
+      /* from Ryan Perkins */
+      .name = "HP Backup and Recovery Manager (?)",
+      .signature = "\x70\x8a\x5d\x46\x35\xc5\x1b\x93"
+                  "\xae\x3d\x86\xfd\xb1\x55\x3e\xe0",
+      .signature_len = 16
+    }
+  };
+#endif
+
 grub_err_t
 grub_partition_msdos_iterate (grub_disk_t disk,
                              int (*hook) (grub_disk_t disk,
@@ -234,13 +273,56 @@ pc_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors,
 
   if (end >= *nsectors + 1)
     {
-      int i;
+      int i, j;
+      char *embed_signature_check;
+      unsigned int orig_nsectors, extra_sectors = 0;
+
+      orig_nsectors = *nsectors;
       *nsectors = end - 1;
       *sectors = grub_malloc (*nsectors * sizeof (**sectors));
       if (!*sectors)
        return grub_errno;
       for (i = 0; i < *nsectors; i++)
        (*sectors)[i] = 1 + i;
+
+      /* Check for software that is already using parts of the embedding
+       * area.
+       */
+      embed_signature_check = grub_malloc (GRUB_DISK_SECTOR_SIZE);
+      for (i = 0; i < *nsectors; i++)
+       {
+         if (grub_disk_read (disk, (*sectors)[i], 0, GRUB_DISK_SECTOR_SIZE,
+                             embed_signature_check))
+           continue;
+
+         for (j = 0; j < ARRAY_SIZE (embed_signatures); j++)
+           if (! grub_memcmp (embed_signatures[j].signature,
+                              embed_signature_check,
+                              embed_signatures[j].signature_len))
+             break;
+         if (j == ARRAY_SIZE (embed_signatures))
+           continue;
+         grub_util_warn ("Sector %llu is already in use by %s; avoiding it.  "
+                         "This software may cause boot or other problems in "
+                         "future.  Please ask its authors not to store data "
+                         "in the boot track",
+                         (*sectors)[i], embed_signatures[j].name);
+         extra_sectors++;
+
+         /* Avoid this sector.  */
+         for (j = i; j < *nsectors; j++)
+           (*sectors)[j]++;
+       }
+      grub_free (embed_signature_check);
+
+      if (end + extra_sectors < orig_nsectors + 1)
+       return grub_error (GRUB_ERR_OUT_OF_RANGE,
+                          "Other software is using the embedding area, and "
+                          "there is not enough room for core.img.  Such "
+                          "software is often trying to store data in a way "
+                          "that avoids detection.  We recommend you "
+                          "investigate.");
+
       return GRUB_ERR_NONE;
     }
 
index fa95f94aadedd30c23687cfffd63db3cc7c9f64b..e0c1db8caa37a97e4eba0f55f0ee5cecbc5808ce 100644 (file)
@@ -442,6 +442,13 @@ setup (const char *dir,
       save_blocklists (sectors[i] + grub_partition_get_start (container),
                       0, GRUB_DISK_SECTOR_SIZE);
 
+    /* Make sure that the last blocklist is a terminator.  */
+    if (block == first_block)
+      block--;
+    block->start = 0;
+    block->len = 0;
+    block->segment = 0;
+
     write_rootdev (core_img, root_dev, boot_img, first_sector);
 
     core_img = realloc (core_img, nsec * GRUB_DISK_SECTOR_SIZE);
@@ -458,12 +465,6 @@ setup (const char *dir,
                                      nsec * GRUB_DISK_SECTOR_SIZE
                                      - core_size);
 
-    /* Make sure that the second blocklist is a terminator.  */
-    block = first_block - 1;
-    block->start = 0;
-    block->len = 0;
-    block->segment = 0;
-
     /* Write the core image onto the disk.  */
     for (i = 0; i < nsec; i++)
       grub_disk_write (dest_dev->disk, sectors[i], 0,