summaryrefslogtreecommitdiffstats
path: root/master/debian/branch_embed-sectors.patch
diff options
context:
space:
mode:
Diffstat (limited to 'master/debian/branch_embed-sectors.patch')
-rw-r--r--master/debian/branch_embed-sectors.patch247
1 files changed, 247 insertions, 0 deletions
diff --git a/master/debian/branch_embed-sectors.patch b/master/debian/branch_embed-sectors.patch
new file mode 100644
index 0000000..9b16423
--- /dev/null
+++ b/master/debian/branch_embed-sectors.patch
@@ -0,0 +1,247 @@
+Description: Detect other software using embedding area
+ When embedding the core image in a post-MBR gap, check for and avoid
+ sectors matching any of the signatures in embed_signatures.
+Author: Colin Watson <cjwatson@ubuntu.com>
+Origin: upstream, http://bzr.sv.gnu.org/r/grub/branches/embed-sectors/
+Forwarded: http://lists.gnu.org/archive/html/grub-devel/2010-08/msg00137.html
+Last-Update: 2011-04-21
+
+Index: b/ChangeLog.embed-sectors
+===================================================================
+--- /dev/null
++++ b/ChangeLog.embed-sectors
+@@ -0,0 +1,12 @@
++2011-03-14 Colin Watson <cjwatson@ubuntu.com>
++
++ * include/grub/partition.h (grub_partition_map): Change prototype of
++ embed to take a maximum value for nsectors.
++ * grub-core/partmap/msdos.c (embed_signatures): New array.
++ (pc_partition_map_embed): Check for and avoid sectors matching any
++ of the signatures in embed_signatures, up to max_nsectors.
++ * grub-core/partmap/gpt.c (gpt_partition_map_embed): Restrict
++ returned sector map to max_nsectors.
++ * util/grub-setup.c (setup): Allow for the embedding area being
++ split into multiple blocklists. Tell dest_partmap->embed the
++ maximum number of sectors we care about.
+Index: b/grub-core/partmap/gpt.c
+===================================================================
+--- a/grub-core/partmap/gpt.c
++++ b/grub-core/partmap/gpt.c
+@@ -127,6 +127,7 @@
+ #ifdef GRUB_UTIL
+ static grub_err_t
+ gpt_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors,
++ unsigned int max_nsectors,
+ grub_embed_type_t embed_type,
+ grub_disk_addr_t **sectors)
+ {
+@@ -176,6 +177,8 @@
+ " embedding won't be possible!");
+
+ *nsectors = len;
++ if (*nsectors > max_nsectors)
++ *nsectors = max_nsectors;
+ *sectors = grub_malloc (*nsectors * sizeof (**sectors));
+ if (!*sectors)
+ return grub_errno;
+Index: b/grub-core/partmap/msdos.c
+===================================================================
+--- a/grub-core/partmap/msdos.c
++++ b/grub-core/partmap/msdos.c
+@@ -29,6 +29,66 @@
+ static struct grub_partition_map grub_msdos_partition_map;
+
+
++#ifdef GRUB_UTIL
++#include <grub/emu/misc.h>
++
++struct embed_signature
++{
++ const char *name;
++ const char *signature;
++ int signature_len;
++ enum { TYPE_SOFTWARE, TYPE_RAID } type;
++};
++
++const char message_warn[][200] = {
++ [TYPE_RAID] = "Sector %llu is already in use by %s; avoiding it. "
++ "Please ask the manufacturer not to store data in MBR gap",
++ [TYPE_SOFTWARE] = "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"
++};
++
++
++/* 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,
++ .type = TYPE_SOFTWARE
++ },
++ {
++ .name = "FlexNet",
++ .signature = "\xd4\x41\xa0\xf5\x03\x00\x03\x00",
++ .signature_len = 8,
++ .type = TYPE_SOFTWARE
++ },
++ {
++ .name = "FlexNet",
++ .signature = "\xd8\x41\xa0\xf5\x02\x00\x02\x00",
++ .signature_len = 8,
++ .type = TYPE_SOFTWARE
++ },
++ {
++ /* 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,
++ .type = TYPE_SOFTWARE
++ },
++ {
++ .name = "HighPoint RAID controller",
++ .signature = "ycgl",
++ .signature_len = 4,
++ .type = TYPE_RAID
++ }
++ };
++#endif
++
+ grub_err_t
+ grub_partition_msdos_iterate (grub_disk_t disk,
+ int (*hook) (grub_disk_t disk,
+@@ -148,6 +208,7 @@
+ #ifdef GRUB_UTIL
+ static grub_err_t
+ pc_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors,
++ unsigned int max_nsectors,
+ grub_embed_type_t embed_type,
+ grub_disk_addr_t **sectors)
+ {
+@@ -236,13 +297,65 @@
+
+ if (end >= *nsectors + 2)
+ {
+- unsigned i;
++ unsigned i, j;
++ char *embed_signature_check;
++ unsigned int orig_nsectors, avail_nsectors;
++
++ orig_nsectors = *nsectors;
+ *nsectors = end - 2;
++ avail_nsectors = *nsectors;
++ if (*nsectors > max_nsectors)
++ *nsectors = max_nsectors;
+ *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 (message_warn[embed_signatures[j].type],
++ (*sectors)[i], embed_signatures[j].name);
++ avail_nsectors--;
++ if (avail_nsectors < *nsectors)
++ *nsectors = avail_nsectors;
++
++ /* Avoid this sector. */
++ for (j = i; j < *nsectors; j++)
++ (*sectors)[j]++;
++
++ /* Have we run out of space? */
++ if (avail_nsectors < orig_nsectors)
++ break;
++
++ /* Make sure to check the next sector. */
++ i--;
++ }
++ grub_free (embed_signature_check);
++
++ if (*nsectors < orig_nsectors)
++ 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: b/include/grub/partition.h
+===================================================================
+--- a/include/grub/partition.h
++++ b/include/grub/partition.h
+@@ -49,6 +49,7 @@
+ #ifdef GRUB_UTIL
+ /* Determine sectors available for embedding. */
+ grub_err_t (*embed) (struct grub_disk *disk, unsigned int *nsectors,
++ unsigned int max_nsectors,
+ grub_embed_type_t embed_type,
+ grub_disk_addr_t **sectors);
+ #endif
+Index: b/util/grub-setup.c
+===================================================================
+--- a/util/grub-setup.c
++++ b/util/grub-setup.c
+@@ -428,10 +428,8 @@
+ }
+
+ nsec = core_sectors;
+- err = dest_partmap->embed (dest_dev->disk, &nsec,
++ err = dest_partmap->embed (dest_dev->disk, &nsec, 2 * core_sectors,
+ GRUB_EMBED_PCBIOS, &sectors);
+- if (nsec > 2 * core_sectors)
+- nsec = 2 * core_sectors;
+
+ if (err)
+ {
+@@ -460,6 +458,13 @@
+ 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);
+@@ -476,12 +481,6 @@
+ 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,