* 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.
This commit is contained in:
parent
03df09c7c8
commit
1e44c52a69
3 changed files with 97 additions and 7 deletions
7
ChangeLog.embed-sectors
Normal file
7
ChangeLog.embed-sectors
Normal file
|
@ -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.
|
|
@ -27,6 +27,45 @@
|
|||
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;
|
||||
};
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue