diff options
author | James Clarke <jrtc27@jrtc27.com> | 2016-10-17 22:16:01 +0200 |
---|---|---|
committer | Jes Sorensen <Jes.Sorensen@redhat.com> | 2016-10-19 18:38:02 +0200 |
commit | 8e2bca513efc5deccb11cb90bad3c0891c4929e3 (patch) | |
tree | b5ac710fc39b07c3fd6e4d5cc4442c3ba5974495 /util.c | |
parent | super-intel: Reduce excessive parenthesis abuse (diff) | |
download | mdadm-8e2bca513efc5deccb11cb90bad3c0891c4929e3.tar.xz mdadm-8e2bca513efc5deccb11cb90bad3c0891c4929e3.zip |
Fix bus error when accessing MBR partition records
Since the MBR layout only has partition records as 2-byte aligned, the
32-bit fields in them are not aligned. Thus, they cannot be accessed on
some architectures (such as SPARC) by using a "struct MBR_part_record *"
pointer, as the compiler can assume that the pointer is properly aligned.
Instead, the records must be accessed by going through the MBR struct
itself every time.
Signed-off-by: James Clarke <jrtc27@jrtc27.com>
Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 18 |
1 files changed, 11 insertions, 7 deletions
@@ -1412,7 +1412,6 @@ static int get_gpt_last_partition_end(int fd, unsigned long long *endofpart) static int get_last_partition_end(int fd, unsigned long long *endofpart) { struct MBR boot_sect; - struct MBR_part_record *part; unsigned long long curr_part_end; unsigned part_nr; int retval = 0; @@ -1429,21 +1428,26 @@ static int get_last_partition_end(int fd, unsigned long long *endofpart) if (boot_sect.magic == MBR_SIGNATURE_MAGIC) { retval = 1; /* found the correct signature */ - part = boot_sect.parts; for (part_nr = 0; part_nr < MBR_PARTITIONS; part_nr++) { + /* + * Have to make every access through boot_sect rather + * than using a pointer to the partition table (or an + * entry), since the entries are not properly aligned. + */ + /* check for GPT type */ - if (part->part_type == MBR_GPT_PARTITION_TYPE) { + if (boot_sect.parts[part_nr].part_type == + MBR_GPT_PARTITION_TYPE) { retval = get_gpt_last_partition_end(fd, endofpart); break; } /* check the last used lba for the current partition */ - curr_part_end = __le32_to_cpu(part->first_sect_lba) + - __le32_to_cpu(part->blocks_num); + curr_part_end = + __le32_to_cpu(boot_sect.parts[part_nr].first_sect_lba) + + __le32_to_cpu(boot_sect.parts[part_nr].blocks_num); if (curr_part_end > *endofpart) *endofpart = curr_part_end; - - part++; } } else { /* Unknown partition table */ |