From 95ef1a54cf42458bbf51b65aac40c5253167fe74 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 30 Apr 2013 17:34:29 +0200 Subject: [PATCH] * grub-core/partmap/amiga.c: Fix size of checksummed block. --- ChangeLog | 4 ++++ grub-core/partmap/amiga.c | 25 +++++++++++++++++-------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0485a01f1..b0ae4eebf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-04-30 Vladimir Serbinenko + + * grub-core/partmap/amiga.c: Fix size of checksummed block. + 2013-04-29 Vladimir Serbinenko * configure.ac: Use -mcmodel=large on x86_64-emu as well. diff --git a/grub-core/partmap/amiga.c b/grub-core/partmap/amiga.c index 213d7074e..97f71600f 100644 --- a/grub-core/partmap/amiga.c +++ b/grub-core/partmap/amiga.c @@ -25,6 +25,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); +#define AMIGA_CHECKSUM_WORDS 128 + struct grub_amiga_rdsk { /* "RDSK". */ @@ -39,7 +41,7 @@ struct grub_amiga_rdsk grub_uint32_t partitionlst; grub_uint32_t fslst; - grub_uint32_t unused[128 - 9]; + grub_uint32_t unused[AMIGA_CHECKSUM_WORDS - 9]; } __attribute__ ((packed)); struct grub_amiga_partition @@ -47,7 +49,7 @@ struct grub_amiga_partition /* "PART". */ grub_uint8_t magic[4]; #define GRUB_AMIGA_PART_MAGIC "PART" - grub_int32_t size; + grub_uint32_t size; grub_int32_t checksum; grub_uint32_t scsihost; grub_uint32_t next; @@ -67,7 +69,7 @@ struct grub_amiga_partition grub_uint32_t highcyl; grub_uint32_t firstcyl; - grub_uint32_t unused[128 - 44]; + grub_uint32_t unused[AMIGA_CHECKSUM_WORDS - 44]; } __attribute__ ((packed)); 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 -amiga_partition_map_checksum (void *buf, grub_size_t sz) +amiga_partition_map_checksum (void *buf) { grub_uint32_t *ptr = buf; 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++) r += grub_be_to_cpu32 (*ptr); + return r; } @@ -105,7 +114,7 @@ amiga_partition_map_iterate (grub_disk_t disk, if (grub_memcmp (rdsk.magic, GRUB_AMIGA_RDSK_MAGIC, sizeof (rdsk.magic)) == 0 - && amiga_partition_map_checksum (&rdsk, sizeof (rdsk)) == 0) + && amiga_partition_map_checksum (&rdsk) == 0) { /* Found the first PART block. */ 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, 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, "invalid Amiga partition map"); /* 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.block_per_track)); - part.offset = (grub_off_t) next * 512; + part.offset = next; part.number = partno; part.index = 0; part.partmap = &grub_amiga_partition_map;