Bug fix: iso_write_opts_set_part_like_isohybrid() did not cause a MBR partition table if the partitions are data files in the ISO rather than appended

This commit is contained in:
Thomas Schmitt 2022-04-23 09:30:34 +02:00
parent 99251ade08
commit 1d61b518b5
2 changed files with 57 additions and 42 deletions

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2002 - 2008 H. Peter Anvin
* Copyright (c) 2008 - 2015 Thomas Schmitt
* Copyright (c) 2008 - 2022 Thomas Schmitt
* with special credits to Matthew Garrett for isohybrid with GPT and APM
*
* This file is part of the libisofs project; you can redistribute it and/or
@ -625,8 +625,12 @@ static uint32_t iso_make_mbr_id(Ecma119Image *t, int flag)
/*
* @param flag bit0= make own random MBR Id from current time
* >>> or from overridden modification time
* or from overridden modification time
* bit1= create protective MBR as of UEFI/GPT specs
* bit2= write only partition table
* do not insert APM mockup head
* do not treat bytes before code as isohybrid MBR
* do not create MBR id
*/
int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t,
int part_offset, int part_number, int fs_type,
@ -662,39 +666,44 @@ int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t,
if (ret < 0)
return ret;
/* The rest of APM has already been written by iso_write_apm().
But the isohybrid APM head differs from the hfsplus_writer APM head.
*/
ret = insert_apm_head(buf, apm_count);
if (ret < 0)
return ret;
/* Padding of image_size to a multiple of sector_count*head_count
happens already at compute time and is implemented by
an appropriate increase of Ecma119Image->tail_blocks.
*/
wpt = (char *) buf + 432;
/* write qword boot_lba # Offset 432
*/
hd_boot_lba = ((off_t) boot_lba) * (off_t) 4;
lsb_to_buf(&wpt, hd_boot_lba & 0xffffffff, 32, 0);
lsb_to_buf(&wpt, hd_boot_lba >> 32, 32, 0);
/* write dword mbr_id # Offset 440
(here some 32-bit random value with no crypto strength)
*/
if (flag & 1) {
id = iso_make_mbr_id(t, 0);
lsb_to_buf(&wpt, id, 32, 0);
if(flag & 4) {
wpt= (char *) buf + 446;
} else {
wpt+= 4;
}
/* write word 0 # Offset 444
*/
lsb_to_buf(&wpt, 0, 16, 0);
/* The rest of APM has already been written by iso_write_apm().
But the isohybrid APM head differs from the hfsplus_writer APM head.
*/
ret = insert_apm_head(buf, apm_count);
if (ret < 0)
return ret;
/* Padding of image_size to a multiple of sector_count*head_count
happens already at compute time and is implemented by
an appropriate increase of Ecma119Image->tail_blocks.
*/
wpt = (char *) buf + 432;
/* write qword boot_lba # Offset 432
*/
hd_boot_lba = ((off_t) boot_lba) * (off_t) 4;
lsb_to_buf(&wpt, hd_boot_lba & 0xffffffff, 32, 0);
lsb_to_buf(&wpt, hd_boot_lba >> 32, 32, 0);
/* write dword mbr_id # Offset 440
(here some 32-bit random value with no crypto strength)
*/
if (flag & 1) {
id = iso_make_mbr_id(t, 0);
lsb_to_buf(&wpt, id, 32, 0);
} else {
wpt+= 4;
}
/* write word 0 # Offset 444
*/
lsb_to_buf(&wpt, 0, 16, 0);
}
/* # Offset 446
*/

View File

@ -1912,7 +1912,7 @@ int iso_ensure_mbr_part_table(Ecma119Image *t, uint32_t img_blocks,
if (t->opts->iso_mbr_part_type >= 0 &&
t->opts->iso_mbr_part_type <= 255)
part_type= t->opts->iso_mbr_part_type;
ret = write_mbr_partition_entry(found_part, part_type,
ret = write_mbr_partition_entry(found_part, part_type,
start_lba, img_blocks * 4,
t->partition_secs_per_head,
t->partition_heads_per_cyl, buf, 2);
@ -2006,8 +2006,10 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf, int flag)
*/
apm_flag = 0;
if (sa_type == 0 && (t->system_area_options & 3) == 2) {
do_isohybrid = 1;
if (sa_type == 0 && ((t->system_area_options & 3) == 2 ||
t->opts->part_like_isohybrid)) {
if (sa_type == 0 && (t->system_area_options & 3) == 2)
do_isohybrid = 1;
/* >>> Coordinate with partprepend writer */
/* <<< provisory trap */
@ -2078,9 +2080,12 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf, int flag)
/* >>> ??? change first partition type to 0xee */;
}
} else if (do_isohybrid) {
/* Patch externally provided system area as isohybrid MBR */
if (t->catalog == NULL || t->system_area_data == NULL) {
} else if (do_isohybrid || t->opts->part_like_isohybrid) {
/* Patch externally provided system area as isohybrid MBR
or at least write an MBR partition table as of isohybrid
*/
if ((t->catalog == NULL || t->system_area_data == NULL) &&
do_isohybrid) {
/* isohybrid makes only sense together with ISOLINUX boot image
and externally provided System Area.
*/
@ -2089,12 +2094,13 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf, int flag)
if (gpt_count > 0 || apm_count > 0)
part_type = 0x00;
else {
else
part_type = 0x17;
/* By tradition, real isohybrid insists in 0x00 if GPT or APM */
if (part_type != 0x00 || !do_isohybrid)
if (t->opts->iso_mbr_part_type >= 0 &&
t->opts->iso_mbr_part_type <= 255)
part_type= t->opts->iso_mbr_part_type;
}
if (t->opts->appended_as_gpt && t->have_appended_partitions) {
part_type = 0xee;
@ -2109,7 +2115,7 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf, int flag)
*/;
ret = make_isolinux_mbr(&img_blocks, t, 0, 1, part_type, buf,
1 | no_boot_mbr);
1 | no_boot_mbr | ((!do_isohybrid) << 2));
if (ret != 1)
return ret;
} else if (sa_type == 1) {