From ec35bb21c09bff36f3b12c084e71f96aa984d263 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Wed, 30 Dec 2015 18:56:32 +0100 Subject: [PATCH] Provisory new pseudo path for El Torito boot images: --interval:appened_partition_N:all:: --- libisofs/ecma119.c | 23 ++++- libisofs/ecma119.h | 13 ++- libisofs/eltorito.c | 160 +++++++++++++++++++++++++--------- libisofs/eltorito.h | 3 + libisofs/libisofs.h | 16 +++- libisofs/make_isohybrid_mbr.c | 59 ++++++++++--- libisofs/system_area.c | 6 ++ 7 files changed, 220 insertions(+), 60 deletions(-) diff --git a/libisofs/ecma119.c b/libisofs/ecma119.c index f59f3aa..4429e91 100644 --- a/libisofs/ecma119.c +++ b/libisofs/ecma119.c @@ -104,6 +104,8 @@ void ecma119_image_free(Ecma119Image *t) free(t->output_charset); if (t->bootsrc != NULL) free(t->bootsrc); + if (t->boot_appended_idx != NULL) + free(t->boot_appended_idx); if (t->system_area_data != NULL) free(t->system_area_data); if (t->checksum_ctx != NULL) { /* dispose checksum context */ @@ -567,8 +569,13 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer) vol.vol_desc_version[0] = 1; strncpy_pad((char*)vol.system_id, system_id, 32); strncpy_pad((char*)vol.volume_id, vol_id, 32); - iso_bb(vol.vol_space_size, t->vol_space_size - t->eff_partition_offset, - 4); + if (t->pvd_size_is_total_size) { + iso_bb(vol.vol_space_size, + t->total_size / 2048 - t->eff_partition_offset, 4); + } else { + iso_bb(vol.vol_space_size, + t->vol_space_size - t->eff_partition_offset, 4); + } iso_bb(vol.vol_set_size, (uint32_t) 1, 2); iso_bb(vol.vol_seq_number, (uint32_t) 1, 2); iso_bb(vol.block_size, (uint32_t) BLOCK_SIZE, 2); @@ -2376,12 +2383,16 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img) target->num_bootsrc = target->catalog->num_bootimages; target->bootsrc = calloc(target->num_bootsrc + 1, sizeof(IsoFileSrc *)); - if (target->bootsrc == NULL) { + target->boot_appended_idx = calloc(target->num_bootsrc + 1, + sizeof(int)); + if (target->bootsrc == NULL || target->boot_appended_idx == NULL) { ret = ISO_OUT_OF_MEM; goto target_cleanup; } - for (i= 0; i < target->num_bootsrc; i++) + for (i= 0; i < target->num_bootsrc; i++) { target->bootsrc[i] = NULL; + target->boot_appended_idx[i] = -1; + } } else { target->num_bootsrc = 0; target->bootsrc = NULL; @@ -2448,6 +2459,10 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img) goto target_cleanup; } + target->total_size = 0; + target->vol_space_size = 0; + target->pvd_size_is_total_size = 0; + target->checksum_idx_counter = 0; target->checksum_ctx = NULL; target->checksum_counter = 0; diff --git a/libisofs/ecma119.h b/libisofs/ecma119.h index c31d42e..d4d13cb 100644 --- a/libisofs/ecma119.h +++ b/libisofs/ecma119.h @@ -554,10 +554,19 @@ struct ecma119_image time_t now; /**< Time at which writing began. */ - /** Total size of the output. This only includes the current volume. */ + /* Total size of the output. Counted in bytes. + * Includes ISO filesystem and appended data. + */ off_t total_size; + + /** Size actually governed by the ISO filesystem part of the output */ uint32_t vol_space_size; + /* 1= write the total size into the PVD of the ISO, + * 0= write vol_space_size + */ + int pvd_size_is_total_size; + /* Bytes already written to image output */ off_t bytes_written; /* just for progress notification */ @@ -640,6 +649,8 @@ struct ecma119_image int num_bootsrc; IsoFileSrc **bootsrc; /* location of the boot images in the new image */ + int *boot_appended_idx; /* Appended partition which serve as boot images */ + /* * System Area related information */ diff --git a/libisofs/eltorito.c b/libisofs/eltorito.c index 75503e7..c1c045b 100644 --- a/libisofs/eltorito.c +++ b/libisofs/eltorito.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2007 Vreixo Formoso - * Copyright (c) 2010 - 2014 Thomas Schmitt + * Copyright (c) 2010 - 2015 Thomas Schmitt * * This file is part of the libisofs project; you can redistribute it and/or * modify it under the terms of the GNU General Public License version 2 @@ -19,6 +19,7 @@ #include "image.h" #include "messages.h" #include "writer.h" +#include "ecma119.h" #include #include @@ -323,36 +324,61 @@ int create_image(IsoImage *image, const char *image_path, struct el_torito_boot_image *boot; int boot_media_type = 0; int load_sectors = 0; /* number of sector to load */ + int part_idx = -1; unsigned char partition_type = 0; off_t size; - IsoNode *imgfile; - IsoStream *stream; + IsoNode *imgfile = NULL; + IsoStream *stream = NULL; *bootnode = NULL; - ret = iso_tree_path_to_node(image, image_path, &imgfile); - if (ret < 0) { - return ret; - } - if (ret == 0) { - iso_msg_submit(image->id, ISO_NODE_DOESNT_EXIST, 0, + + if (strncmp(image_path, "--interval:appended_partition_", 30) == 0) { + /* --interval:appended_partition_N... */ + if (type != ELTORITO_NO_EMUL) { + + /* >>> ??? lift this ban by making a temporary IsoStream from + partition source, determine size, + and read ELTORITO_HARD_DISC_EMUL MBR ? + */ + + iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0, + "Appended partition cannot serve as El Torito boot image with FD/HD emulation"); + return ISO_BOOT_IMAGE_NOT_VALID; + } + sscanf(image_path + 30, "%d", &part_idx); + if (part_idx < 1 || part_idx > ISO_MAX_PARTITIONS) { + iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0, + "Appended partition index for El Torito boot image is out of range"); + return ISO_BOOT_IMAGE_NOT_VALID; + } + part_idx--; + size = 1; + } else { + ret = iso_tree_path_to_node(image, image_path, &imgfile); + if (ret < 0) { + return ret; + } + if (ret == 0) { + iso_msg_submit(image->id, ISO_NODE_DOESNT_EXIST, 0, "El Torito boot image file missing in ISO image: '%s'", image_path); - return ISO_NODE_DOESNT_EXIST; + return ISO_NODE_DOESNT_EXIST; + } + + if (imgfile->type != LIBISO_FILE) { + return ISO_BOOT_IMAGE_NOT_VALID; + } + *bootnode = (IsoFile *) imgfile; + + stream = ((IsoFile*)imgfile)->stream; + + /* we need to read the image at least two times */ + if (!iso_stream_is_repeatable(stream)) { + return ISO_BOOT_IMAGE_NOT_VALID; + } + + size = iso_stream_get_size(stream); } - - if (imgfile->type != LIBISO_FILE) { - return ISO_BOOT_IMAGE_NOT_VALID; - } - *bootnode = (IsoFile *) imgfile; - - stream = ((IsoFile*)imgfile)->stream; - - /* we need to read the image at least two times */ - if (!iso_stream_is_repeatable(stream)) { - return ISO_BOOT_IMAGE_NOT_VALID; - } - - size = iso_stream_get_size(stream); if (size <= 0) { iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0, "Boot image file is empty"); @@ -441,7 +467,9 @@ int create_image(IsoImage *image, const char *image_path, return ISO_OUT_OF_MEM; } boot->image = (IsoFile*)imgfile; - iso_node_ref(imgfile); /* get our ref */ + boot->appended_idx = part_idx; + if (imgfile != NULL) + iso_node_ref(imgfile); /* get our ref */ boot->bootable = 1; boot->seems_boot_info_table = 0; boot->seems_grub2_boot_info = 0; @@ -538,8 +566,9 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path, catalog->bootimages[i] = NULL; catalog->node = cat_node; catalog->sort_weight = 1000000000; /* very high */ - if (!(boot_node->explicit_weight || boot_node->from_old_session)) - boot_node->sort_weight = 2; + if (boot_node != NULL) + if (!(boot_node->explicit_weight || boot_node->from_old_session)) + boot_node->sort_weight = 2; iso_node_ref((IsoNode*)cat_node); image->bootcat = catalog; @@ -555,7 +584,8 @@ boot_image_cleanup:; iso_node_unref((IsoNode*)cat_node); } if (boot_image) { - iso_node_unref((IsoNode*)boot_image->image); + if (boot_image->image != NULL) + iso_node_unref((IsoNode*)boot_image->image); free(boot_image); } return ret; @@ -719,8 +749,9 @@ int iso_image_add_boot_image(IsoImage *image, const char *image_path, ret = create_image(image, image_path, type, &boot_img, &boot_node); if (ret < 0) return ret; - if (!(boot_node->explicit_weight || boot_node->from_old_session)) - boot_node->sort_weight = 2; + if (boot_node != NULL) + if (!(boot_node->explicit_weight || boot_node->from_old_session)) + boot_node->sort_weight = 2; catalog->bootimages[catalog->num_bootimages] = boot_img; catalog->num_bootimages++; if (boot != NULL) @@ -827,12 +858,13 @@ write_section_header(uint8_t *buf, Ecma119Image *t, int idx, int num_entries) * Usable for the Default Entry * and for Section Entries with Selection criteria type == 0 */ -static void -write_section_entry(uint8_t *buf, Ecma119Image *t, int idx) +static +int write_section_entry(uint8_t *buf, Ecma119Image *t, int idx) { struct el_torito_boot_image *img; struct el_torito_section_entry *se = (struct el_torito_section_entry*)buf; + int app_idx; img = t->catalog->bootimages[idx]; @@ -840,16 +872,37 @@ write_section_entry(uint8_t *buf, Ecma119Image *t, int idx) se->boot_media_type[0] = img->type; iso_lsb(se->load_seg, img->load_seg, 2); se->system_type[0] = img->partition_type; - iso_lsb(se->sec_count, img->load_size, 2); - iso_lsb(se->block, t->bootsrc[idx]->sections[0].block, 4); + + if (t->boot_appended_idx[idx] >= 0) { + app_idx = t->boot_appended_idx[idx]; + if (t->appended_part_size[app_idx] * 4 > 65535) { + if (img->platform_id == 0xef) + iso_lsb(se->sec_count, 0, 2); + else + iso_lsb(se->sec_count, 65535, 2); + } else { + if (t->appended_part_size[app_idx] == 0) { + iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0, + "Appended partition which shall serve as boot image does not exist"); + return ISO_BOOT_IMAGE_NOT_VALID; + } + iso_lsb(se->sec_count, t->appended_part_size[app_idx] * 4, 2); + } + iso_lsb(se->block, t->appended_part_start[app_idx], 4); + } else { + iso_lsb(se->sec_count, img->load_size, 2); + iso_lsb(se->block, t->bootsrc[idx]->sections[0].block, 4); + } + se->selec_criteria[0] = img->selection_crit[0]; memcpy(se->vendor_sc, img->selection_crit + 1, 19); + return ISO_SUCCESS; } static int catalog_open(IsoStream *stream) { - int i, j, k, num_entries; + int i, j, k, num_entries, ret; struct catalog_stream *data; uint8_t *wpt; struct el_torito_boot_catalog *cat; @@ -873,7 +926,9 @@ int catalog_open(IsoStream *stream) boots[0]->platform_id, boots[0]->id_string); /* write default entry = first boot image */ - write_section_entry(data->buffer + 32, data->target, 0); + ret = write_section_entry(data->buffer + 32, data->target, 0); + if (ret < 0) + return ret; /* IMPORTANT: The maximum number of boot images must fit into BLOCK_SIZE */ wpt = data->buffer + 64; @@ -894,7 +949,9 @@ int catalog_open(IsoStream *stream) write_section_header(wpt, data->target, i, num_entries); wpt += 32; for (j = 0; j < num_entries; j++) { - write_section_entry(wpt, data->target, i); + ret = write_section_entry(wpt, data->target, i); + if (ret < 0) + return ret; wpt += 32; i++; } @@ -1132,6 +1189,9 @@ int patch_boot_info_table(uint8_t *buf, Ecma119Image *t, return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0, "Isolinux image too small. We won't patch it."); } + if (t->bootsrc[idx] == NULL) + return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0, + "Cannot apply ISOLINUX patching outside of ISO 9660 filesystem."); ret = make_boot_info_table(buf, t->opts->ms_block + (uint32_t) 16, t->bootsrc[idx]->sections[0].block, (uint32_t) imgsize); @@ -1151,7 +1211,10 @@ int patch_grub2_boot_image(uint8_t *buf, Ecma119Image *t, if (imgsize < pos + 8) return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0, - "Isolinux image too small for GRUB2. Will not patch it."); + "Boot image too small for GRUB2. Will not patch it."); + if (t->bootsrc[idx] == NULL) + return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0, + "Cannot apply GRUB2 patching outside of ISO 9660 filesystem."); blk = ((uint64_t) t->bootsrc[idx]->sections[0].block) * 4 + offst; iso_lsb((buf + pos), blk & 0xffffffff, 4); iso_lsb((buf + pos + 4), blk >> 32, 4); @@ -1174,6 +1237,10 @@ int iso_patch_eltoritos(Ecma119Image *t) for (idx = 0; idx < t->catalog->num_bootimages; idx++) { if (!(t->catalog->bootimages[idx]->isolinux_options & 0x201)) continue; + if (t->bootsrc[idx] == NULL) + return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0, + "Cannot apply boot image patching outside of ISO 9660 filesystem"); + original = t->bootsrc[idx]->stream; size = (size_t) iso_stream_get_size(original); if (size > Libisofs_elto_max_patchablE) @@ -1281,8 +1348,8 @@ int eltorito_writer_create(Ecma119Image *target) { int ret, idx, outsource_efi = 0; IsoImageWriter *writer; - IsoFile *bootimg; - IsoFileSrc *src; + IsoFile *bootimg = NULL; + IsoFileSrc *src = NULL; writer = calloc(1, sizeof(IsoImageWriter)); if (writer == NULL) { @@ -1315,6 +1382,19 @@ int eltorito_writer_create(Ecma119Image *target) if (strcmp(target->opts->efi_boot_partition, "--efi-boot-image") == 0) outsource_efi = 1; for (idx = 0; idx < target->catalog->num_bootimages; idx++) { + target->bootsrc[idx] = NULL; + if (target->catalog->bootimages[idx]->appended_idx >= 0) { + /* Use an appended partition as boot image rather than IsoFile */ + target->boot_appended_idx[idx] = + target->catalog->bootimages[idx]->appended_idx; + if (((target->system_area_options >> 2) & 0x3f) == 0 && + (target->system_area_options & 3) == 1) { + /* ISO will not be a partition. It can span the whole image. */ + target->pvd_size_is_total_size = 1; + } + continue; + } + bootimg = target->catalog->bootimages[idx]->image; ret = iso_file_src_create(target, bootimg, &src); if (ret < 0) { diff --git a/libisofs/eltorito.h b/libisofs/eltorito.h index 7eb1bbb..a027d1d 100644 --- a/libisofs/eltorito.h +++ b/libisofs/eltorito.h @@ -53,6 +53,9 @@ struct el_torito_boot_catalog { struct el_torito_boot_image { IsoFile *image; + /* Overrides .image if >= 0 : array index of appended partition */ + int appended_idx; + unsigned int bootable:1; /**< If the entry is bootable. */ /** * Whether the boot image seems to contain a boot_info_table diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index e26c285..fad3649 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -3402,6 +3402,9 @@ int iso_image_get_pvd_times(IsoImage *image, * returns an error and the image remains unmodified. * @param image_path * The absolute path of a IsoFile to be used as default boot image. + +>>> or --interval:appended_partition_$number... + * @param type * The boot media type. This can be one of 3 types: * - Floppy emulation: Boot image file must be exactly @@ -3443,7 +3446,10 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path, * The image to which the boot image shall be added. * returns an error and the image remains unmodified. * @param image_path - * The absolute path of a IsoFile to be used as default boot image. + * The absolute path of a IsoFile to be used as boot image. + +>>> or --interval:appended_partition_$number... + * @param type * The boot media type. See iso_image_set_boot_image * @param flag @@ -3488,6 +3494,9 @@ int iso_image_add_boot_image(IsoImage *image, const char *image_path, * @param imgnode * When not NULL, it will be filled with the image tree node. No extra ref * is added, you can use iso_node_ref() to get one if you need it. + +>>> The returned value is NULL if the boot image source is no IsoFile. + * @param catnode * When not NULL, it will be filled with the catnode tree node. No extra * ref is added, you can use iso_node_ref() to get one if you need it. @@ -3545,6 +3554,11 @@ int iso_image_get_bootcat(IsoImage *image, IsoBoot **catnode, uint32_t *lba, * @param bootnodes * Returns NULL or an allocated array of pointers to the IsoFile nodes * which bear the content of the boot images in boots. + +>>> An array entry is NULL if the boot image source is no IsoFile. + +>>> Need getter for partition index + * @param flag * Bitfield for control purposes. Unused yet. Submit 0. * @return diff --git a/libisofs/make_isohybrid_mbr.c b/libisofs/make_isohybrid_mbr.c index aa89426..a0b66cb 100644 --- a/libisofs/make_isohybrid_mbr.c +++ b/libisofs/make_isohybrid_mbr.c @@ -37,6 +37,8 @@ #include "ecma119.h" #include "eltorito.h" #include "system_area.h" +#include "image.h" +#include "messages.h" /* This code stems from syslinux-3.72/utils/isohybrid, a perl script @@ -60,7 +62,7 @@ license from above stem licenses, typically from LGPL. In case its generosity is needed, here is the 2-clause BSD license: make_isohybrid_mbr.c is copyright 2002-2008 H. Peter Anvin - and 2008-2014 Thomas Schmitt + and 2008-2015 Thomas Schmitt 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. @@ -408,6 +410,7 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128], { int i, ilx_opts, j, ret, num_img; uint32_t block_count; + uint64_t start_block; uint8_t gpt_name[72]; static uint8_t zero_uuid[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; static uint8_t basic_data_uuid[16] = { @@ -430,11 +433,13 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128], num_img = 0; for (i = 0; i < num_img; i++) { ilx_opts = t->catalog->bootimages[i]->isolinux_options; - if (((ilx_opts >> 2) & 63) == 1 || ((ilx_opts >> 2) & 63) == 2) { + if ((((ilx_opts >> 2) & 63) == 1 || ((ilx_opts >> 2) & 63) == 2) && + !(t->boot_appended_idx[i] >= 0 && t->opts->appended_as_gpt)) { if (*gpt_count < 128) gpt_idx[*gpt_count]= i; (*gpt_count)++; - if ((flag & 1) && t->bootsrc[i] != NULL) { + if ((flag & 1) && + (t->bootsrc[i] != NULL || t->boot_appended_idx[i] >= 0)) { /* Register GPT entry */ memset(gpt_name, 0, 72); sprintf((char *) gpt_name, "ISOHybrid%d", *gpt_count); @@ -443,13 +448,21 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128], uuid = hfs_uuid; else uuid = basic_data_uuid; - block_count = 0; - for (j = 0; j < t->bootsrc[i]->nsections; j++) - block_count += t->bootsrc[i]->sections[j].size / 2048; + if (t->boot_appended_idx[i] >= 0) { + block_count = t->appended_part_size[ + t->boot_appended_idx[i]]; + start_block = ((uint64_t) t->appended_part_start[ + t->boot_appended_idx[i]]) * 4; + } else { + block_count = 0; + for (j = 0; j < t->bootsrc[i]->nsections; j++) + block_count += t->bootsrc[i]->sections[j].size / 2048; + start_block = ((uint64_t) t->bootsrc[i]->sections[0].block) + * 4; + } ret = iso_quick_gpt_entry( t->gpt_req, &(t->gpt_req_count), - ((uint64_t) t->bootsrc[i]->sections[0].block) * 4, - ((uint64_t) block_count) * 4, + start_block, ((uint64_t) block_count) * 4, uuid, zero_uuid, gpt_flags, (uint8_t *) gpt_name); if (ret < 0) return ret; @@ -457,13 +470,22 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128], } if ((ilx_opts & 256) && !(flag & 2)) { (*apm_count)++; - if ((flag & 1) && t->bootsrc[i] != NULL) { + if ((flag & 1) && + (t->bootsrc[i] != NULL || t->boot_appended_idx[i] >= 0)) { /* Register APM entry */ - block_count = 0; - for (j = 0; j < t->bootsrc[i]->nsections; j++) - block_count += t->bootsrc[i]->sections[j].size / 2048; + if (t->boot_appended_idx[i] >= 0) { + block_count = t->appended_part_size[ + t->boot_appended_idx[i]]; + start_block = t->appended_part_start[ + t->boot_appended_idx[i]]; + } else { + block_count = 0; + for (j = 0; j < t->bootsrc[i]->nsections; j++) + block_count += t->bootsrc[i]->sections[j].size / 2048; + start_block = t->bootsrc[i]->sections[0].block; + } ret = iso_quick_apm_entry(t->apm_req, &(t->apm_req_count), - t->bootsrc[i]->sections[0].block, + (uint32_t) start_block, block_count, "EFI", "Apple_HFS"); if (ret < 0) return ret; @@ -546,13 +568,18 @@ static int gpt_images_as_mbr_partitions(Ecma119Image *t, char *wpt, 0xfe, 0xff, 0xff, }; + if (t->bootsrc[gpt_idx[*gpt_cursor]] == NULL) { + (*gpt_cursor)++; + return 2; + } + wpt[0] = 0; memcpy(wpt + 1, dummy_chs, 3); ilx_opts = t->catalog->bootimages[gpt_idx[*gpt_cursor]]->isolinux_options; if (((ilx_opts >> 2) & 63) == 2) wpt[4] = 0x00; /* HFS gets marked as "Empty" */ else - ((unsigned char *) wpt)[4] = 0xef; /* "EFI (FAT-12/16/" */ + ((unsigned char *) wpt)[4] = 0xef; /* "EFI (FAT-12/16)" */ memcpy(wpt + 5, dummy_chs, 3); @@ -589,6 +616,10 @@ int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t, struct timeval tv; struct timezone tz; + if (t->bootsrc[0] == NULL) + return iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0, + "Cannot refer by isohybrid MBR to data outside of ISO 9660 filesystem."); + if (flag & 2) { part_number = 1; part_offset = 1; diff --git a/libisofs/system_area.c b/libisofs/system_area.c index b40b743..ba613a1 100644 --- a/libisofs/system_area.c +++ b/libisofs/system_area.c @@ -1820,6 +1820,9 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf) /* Check for isolinux image with magic number of 3.72 and produce an MBR from our built-in template. (Deprecated since 31 Mar 2010) */ + if (t->bootsrc[0] == NULL) + return iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0, + "Cannot refer by isohybrid MBR to data outside of ISO 9660 filesystem."); if (img_blocks < 0x80000000) { int_img_blocks= img_blocks; } else { @@ -2062,6 +2065,9 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf) if (sa_type == 0 && (t->system_area_options & 0x4000) && !do_isohybrid) { /* Patch MBR for GRUB2 */ + if (t->bootsrc[0] == NULL) + return iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0, + "Cannot refer by GRUB2 MBR to data outside of ISO 9660 filesystem."); blk = t->bootsrc[0]->sections[0].block * 4 + Libisofs_grub2_mbr_patch_offsT; wpt = buf + Libisofs_grub2_mbr_patch_poS;