From da5757f802ef9d87f29f1089fff2967e806d9ffa Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 25 Aug 2024 23:05:13 +0200 Subject: [PATCH 1/2] Minor but important changes to minivhd's dynamic/diff vhd handling 1. Changed the first seek_end in create_block to seek_set. 2. Avoid expansion overflow through a check if the block offset is below the total sectors. --- src/disk/minivhd/minivhd_io.c | 65 +++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/src/disk/minivhd/minivhd_io.c b/src/disk/minivhd/minivhd_io.c index 2912cf5b2..2a430f8a4 100644 --- a/src/disk/minivhd/minivhd_io.c +++ b/src/disk/minivhd/minivhd_io.c @@ -37,6 +37,7 @@ #ifndef _FILE_OFFSET_BITS # define _FILE_OFFSET_BITS 64 #endif +#include #include #include #include @@ -45,6 +46,10 @@ #include #include "minivhd.h" #include "internal.h" +#define HAVE_STDARG_H + +#include "cpu.h" +#include <86box/86box.h> /* * The following bit array macros adapted from: @@ -158,7 +163,7 @@ create_block(MVHDMeta *vhdm, int blk) uint8_t footer[MVHD_FOOTER_SIZE] = { 0 }; /* Seek to where the footer SHOULD be */ - mvhd_fseeko64(vhdm->f, -MVHD_FOOTER_SIZE, SEEK_END); + mvhd_fseeko64(vhdm->f, -MVHD_FOOTER_SIZE, SEEK_SET); (void) !fread(footer, sizeof footer, 1, vhdm->f); mvhd_fseeko64(vhdm->f, -MVHD_FOOTER_SIZE, SEEK_END); @@ -334,36 +339,38 @@ mvhd_sparse_diff_write(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *i int sib = 0; ls = offset + transfer_sectors; - for (s = offset; s < ls; s++) { - blk = s / vhdm->sect_per_block; - sib = s % vhdm->sect_per_block; - if (vhdm->bitmap.curr_block != blk && prev_blk >= 0) { - /* Write the sector bitmap for the previous block, before we replace it. */ - write_curr_sect_bitmap(vhdm); - } - - if (vhdm->block_offset[blk] == MVHD_SPARSE_BLK) { - /* "read" the sector bitmap first, before creating a new block, as the bitmap will be - zero either way */ - read_sect_bitmap(vhdm, blk); - create_block(vhdm, blk); - } - - if (blk != prev_blk) { - if (vhdm->bitmap.curr_block != blk) { - read_sect_bitmap(vhdm, blk); - mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR); - } else { - addr = (((int64_t) vhdm->block_offset[blk]) + vhdm->bitmap.sector_count + sib) * - MVHD_SECTOR_SIZE; - mvhd_fseeko64(vhdm->f, addr, SEEK_SET); + if (offset < total_sectors) { + for (s = offset; s < ls; s++) { + blk = s / vhdm->sect_per_block; + sib = s % vhdm->sect_per_block; + if (vhdm->bitmap.curr_block != blk && prev_blk >= 0) { + /* Write the sector bitmap for the previous block, before we replace it. */ + write_curr_sect_bitmap(vhdm); } - prev_blk = blk; - } - fwrite(buff, MVHD_SECTOR_SIZE, 1, vhdm->f); - VHD_SETBIT(vhdm->bitmap.curr_bitmap, sib); - buff += MVHD_SECTOR_SIZE; + if (vhdm->block_offset[blk] == MVHD_SPARSE_BLK) { + /* "read" the sector bitmap first, before creating a new block, as the bitmap will be + zero either way */ + read_sect_bitmap(vhdm, blk); + create_block(vhdm, blk); + } + + if (blk != prev_blk) { + if (vhdm->bitmap.curr_block != blk) { + read_sect_bitmap(vhdm, blk); + mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR); + } else { + addr = (((int64_t) vhdm->block_offset[blk]) + vhdm->bitmap.sector_count + sib) * + MVHD_SECTOR_SIZE; + mvhd_fseeko64(vhdm->f, addr, SEEK_SET); + } + prev_blk = blk; + } + + fwrite(buff, MVHD_SECTOR_SIZE, 1, vhdm->f); + VHD_SETBIT(vhdm->bitmap.curr_bitmap, sib); + buff += MVHD_SECTOR_SIZE; + } } /* And write the sector bitmap for the last block we visited to disk */ From 8c98dcf5e8bd66da6c9af4a65de6bca439141cce Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 25 Aug 2024 23:26:20 +0200 Subject: [PATCH 2/2] Remove the first change. --- src/disk/minivhd/minivhd_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/disk/minivhd/minivhd_io.c b/src/disk/minivhd/minivhd_io.c index 2a430f8a4..ffc6aba44 100644 --- a/src/disk/minivhd/minivhd_io.c +++ b/src/disk/minivhd/minivhd_io.c @@ -163,7 +163,7 @@ create_block(MVHDMeta *vhdm, int blk) uint8_t footer[MVHD_FOOTER_SIZE] = { 0 }; /* Seek to where the footer SHOULD be */ - mvhd_fseeko64(vhdm->f, -MVHD_FOOTER_SIZE, SEEK_SET); + mvhd_fseeko64(vhdm->f, -MVHD_FOOTER_SIZE, SEEK_END); (void) !fread(footer, sizeof footer, 1, vhdm->f); mvhd_fseeko64(vhdm->f, -MVHD_FOOTER_SIZE, SEEK_END);