* grub-core/partmap/amiga.c: Fix size of checksummed block.

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2013-04-30 17:34:29 +02:00
parent 46546fc577
commit 95ef1a54cf
2 changed files with 21 additions and 8 deletions

View file

@ -1,3 +1,7 @@
2013-04-30 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/partmap/amiga.c: Fix size of checksummed block.
2013-04-29 Vladimir Serbinenko <phcoder@gmail.com> 2013-04-29 Vladimir Serbinenko <phcoder@gmail.com>
* configure.ac: Use -mcmodel=large on x86_64-emu as well. * configure.ac: Use -mcmodel=large on x86_64-emu as well.

View file

@ -25,6 +25,8 @@
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
#define AMIGA_CHECKSUM_WORDS 128
struct grub_amiga_rdsk struct grub_amiga_rdsk
{ {
/* "RDSK". */ /* "RDSK". */
@ -39,7 +41,7 @@ struct grub_amiga_rdsk
grub_uint32_t partitionlst; grub_uint32_t partitionlst;
grub_uint32_t fslst; grub_uint32_t fslst;
grub_uint32_t unused[128 - 9]; grub_uint32_t unused[AMIGA_CHECKSUM_WORDS - 9];
} __attribute__ ((packed)); } __attribute__ ((packed));
struct grub_amiga_partition struct grub_amiga_partition
@ -47,7 +49,7 @@ struct grub_amiga_partition
/* "PART". */ /* "PART". */
grub_uint8_t magic[4]; grub_uint8_t magic[4];
#define GRUB_AMIGA_PART_MAGIC "PART" #define GRUB_AMIGA_PART_MAGIC "PART"
grub_int32_t size; grub_uint32_t size;
grub_int32_t checksum; grub_int32_t checksum;
grub_uint32_t scsihost; grub_uint32_t scsihost;
grub_uint32_t next; grub_uint32_t next;
@ -67,7 +69,7 @@ struct grub_amiga_partition
grub_uint32_t highcyl; grub_uint32_t highcyl;
grub_uint32_t firstcyl; grub_uint32_t firstcyl;
grub_uint32_t unused[128 - 44]; grub_uint32_t unused[AMIGA_CHECKSUM_WORDS - 44];
} __attribute__ ((packed)); } __attribute__ ((packed));
static struct grub_partition_map grub_amiga_partition_map; static struct grub_partition_map grub_amiga_partition_map;
@ -75,13 +77,20 @@ static struct grub_partition_map grub_amiga_partition_map;
static grub_uint32_t static grub_uint32_t
amiga_partition_map_checksum (void *buf, grub_size_t sz) amiga_partition_map_checksum (void *buf)
{ {
grub_uint32_t *ptr = buf; grub_uint32_t *ptr = buf;
grub_uint32_t r = 0; grub_uint32_t r = 0;
sz /= sizeof (grub_uint32_t); grub_size_t sz;
/* Fancy and quick way of checking sz >= 512 / 4 = 128. */
if (ptr[1] & ~grub_cpu_to_be32_compile_time (AMIGA_CHECKSUM_WORDS - 1))
sz = AMIGA_CHECKSUM_WORDS;
else
sz = grub_be_to_cpu32 (ptr[1]);
for (; sz; sz--, ptr++) for (; sz; sz--, ptr++)
r += grub_be_to_cpu32 (*ptr); r += grub_be_to_cpu32 (*ptr);
return r; return r;
} }
@ -105,7 +114,7 @@ amiga_partition_map_iterate (grub_disk_t disk,
if (grub_memcmp (rdsk.magic, GRUB_AMIGA_RDSK_MAGIC, if (grub_memcmp (rdsk.magic, GRUB_AMIGA_RDSK_MAGIC,
sizeof (rdsk.magic)) == 0 sizeof (rdsk.magic)) == 0
&& amiga_partition_map_checksum (&rdsk, sizeof (rdsk)) == 0) && amiga_partition_map_checksum (&rdsk) == 0)
{ {
/* Found the first PART block. */ /* Found the first PART block. */
next = grub_be_to_cpu32 (rdsk.partitionlst); next = grub_be_to_cpu32 (rdsk.partitionlst);
@ -128,7 +137,7 @@ amiga_partition_map_iterate (grub_disk_t disk,
if (grub_memcmp (apart.magic, GRUB_AMIGA_PART_MAGIC, if (grub_memcmp (apart.magic, GRUB_AMIGA_PART_MAGIC,
sizeof (apart.magic)) != 0 sizeof (apart.magic)) != 0
|| amiga_partition_map_checksum (&apart, sizeof (apart)) != 0) || amiga_partition_map_checksum (&apart) != 0)
return grub_error (GRUB_ERR_BAD_PART_TABLE, return grub_error (GRUB_ERR_BAD_PART_TABLE,
"invalid Amiga partition map"); "invalid Amiga partition map");
/* Calculate the first block and the size of the partition. */ /* Calculate the first block and the size of the partition. */
@ -140,7 +149,7 @@ amiga_partition_map_iterate (grub_disk_t disk,
* grub_be_to_cpu32 (apart.heads) * grub_be_to_cpu32 (apart.heads)
* grub_be_to_cpu32 (apart.block_per_track)); * grub_be_to_cpu32 (apart.block_per_track));
part.offset = (grub_off_t) next * 512; part.offset = next;
part.number = partno; part.number = partno;
part.index = 0; part.index = 0;
part.partmap = &grub_amiga_partition_map; part.partmap = &grub_amiga_partition_map;