From: Hervé Poussineau Date: Mon, 10 Oct 2022 17:55:10 +0000 (+0200) Subject: vvfat: allow some writes to bootsector X-Git-Tag: v7.2.0-rc0~32^2~54 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d0f95b6ca0241b14d6cc0f366d162684909370a9;p=thirdparty%2Fqemu.git vvfat: allow some writes to bootsector 'reserved1' field in bootsector is used to mark volume dirty, or need to verify. Allow writes to bootsector which only changes the 'reserved1' field. This fixes I/O errors on Windows guests. Resolves: https://bugs.launchpad.net/qemu/+bug/1889421 Signed-off-by: Hervé Poussineau Message-Id: <20221010175511.3414357-2-hpoussin@reactos.org> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- diff --git a/block/vvfat.c b/block/vvfat.c index f9bf8406d3d..e76b42dbafc 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -2993,11 +2993,35 @@ DLOG(checkpoint()); vvfat_close_current_file(s); + if (sector_num == s->offset_to_bootsector && nb_sectors == 1) { + /* + * Write on bootsector. Allow only changing the reserved1 field, + * used to mark volume dirtiness + */ + unsigned char *bootsector = s->first_sectors + + s->offset_to_bootsector * 0x200; + /* + * LATER TODO: if FAT32, this is wrong (see init_directories(), + * which always creates a FAT16 bootsector) + */ + const int reserved1_offset = offsetof(bootsector_t, u.fat16.reserved1); + + for (i = 0; i < 0x200; i++) { + if (i != reserved1_offset && bootsector[i] != buf[i]) { + fprintf(stderr, "Tried to write to protected bootsector\n"); + return -1; + } + } + + /* Update bootsector with the only updatable byte, and return success */ + bootsector[reserved1_offset] = buf[reserved1_offset]; + return 0; + } + /* * Some sanity checks: * - do not allow writing to the boot sector */ - if (sector_num < s->offset_to_fat) return -1;