diff --git a/ChangeLog.embed-sectors b/ChangeLog.embed-sectors index b1d5868e7..a8de67d24 100644 --- a/ChangeLog.embed-sectors +++ b/ChangeLog.embed-sectors @@ -1,7 +1,12 @@ 2011-03-14 Colin Watson + * 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. + 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. + split into multiple blocklists. Tell dest_partmap->embed the + maximum number of sectors we care about. diff --git a/grub-core/partmap/gpt.c b/grub-core/partmap/gpt.c index 7f2c36143..c4c10d73d 100644 --- a/grub-core/partmap/gpt.c +++ b/grub-core/partmap/gpt.c @@ -125,6 +125,7 @@ gpt_partition_map_iterate (grub_disk_t disk, #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) { @@ -174,6 +175,8 @@ gpt_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, " 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; diff --git a/grub-core/partmap/msdos.c b/grub-core/partmap/msdos.c index acfa6f302..0352d6949 100644 --- a/grub-core/partmap/msdos.c +++ b/grub-core/partmap/msdos.c @@ -185,6 +185,7 @@ grub_partition_msdos_iterate (grub_disk_t disk, #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) { @@ -275,10 +276,13 @@ pc_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, { unsigned i, j; char *embed_signature_check; - unsigned int orig_nsectors; + 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; @@ -307,11 +311,20 @@ pc_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, "future. Please ask its authors not to store data " "in the boot track", (*sectors)[i], embed_signatures[j].name); - (*nsectors)--; + 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); diff --git a/include/grub/partition.h b/include/grub/partition.h index e7e00ef7f..13ada8614 100644 --- a/include/grub/partition.h +++ b/include/grub/partition.h @@ -49,6 +49,7 @@ struct grub_partition_map #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 diff --git a/util/grub-setup.c b/util/grub-setup.c index dc2ab0cce..02abb0d1f 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -426,10 +426,8 @@ setup (const char *dir, } 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, §ors); - if (nsec > 2 * core_sectors) - nsec = 2 * core_sectors; if (err) {