From e565b0c6aa95badda918b1c0a8c129ad9da689e0 Mon Sep 17 00:00:00 2001 From: smf- Date: Sun, 6 Nov 2016 12:17:48 +0000 Subject: [PATCH] Fix heap corruption when loading a new chd fails. Throw CHDERR_FILE_NOT_WRITEABLE rather than CHDERR_UNSUPPORTED_VERSION if you try to open an old version for writing [smf] --- src/devices/imagedev/harddriv.cpp | 10 ++++++++-- src/lib/util/chd.cpp | 7 ++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/devices/imagedev/harddriv.cpp b/src/devices/imagedev/harddriv.cpp index 6903e847abd..a6e0276b8ff 100644 --- a/src/devices/imagedev/harddriv.cpp +++ b/src/devices/imagedev/harddriv.cpp @@ -112,8 +112,11 @@ void harddisk_image_device::device_start() void harddisk_image_device::device_stop() { - if (m_hard_disk_handle) + if (m_hard_disk_handle != nullptr) + { hard_disk_close(m_hard_disk_handle); + m_hard_disk_handle = nullptr; + } } image_init_result harddisk_image_device::call_load() @@ -234,8 +237,11 @@ image_init_result harddisk_image_device::internal_load_hd() m_chd = nullptr; - if (m_hard_disk_handle) + if (m_hard_disk_handle != nullptr) + { hard_disk_close(m_hard_disk_handle); + m_hard_disk_handle = nullptr; + } /* open the CHD file */ if (software_entry() != nullptr) diff --git a/src/lib/util/chd.cpp b/src/lib/util/chd.cpp index 19836a8ee2a..0db64344861 100644 --- a/src/lib/util/chd.cpp +++ b/src/lib/util/chd.cpp @@ -2397,10 +2397,7 @@ chd_error chd_file::open_common(bool writeable) if (memcmp(rawheader, "MComprHD", 8) != 0) throw CHDERR_INVALID_FILE; - // only allow writes to the most recent version m_version = be_read(&rawheader[12], 4); - if (writeable && m_version < HEADER_VERSION) - throw CHDERR_UNSUPPORTED_VERSION; // read the header if we support it util::sha1_t parentsha1 = util::sha1_t::null; @@ -2412,6 +2409,10 @@ chd_error chd_file::open_common(bool writeable) default: throw CHDERR_UNSUPPORTED_VERSION; } + // only allow writes to the most recent version + if (m_version < HEADER_VERSION) + m_allow_writes = false; + if (writeable && !m_allow_writes) throw CHDERR_FILE_NOT_WRITEABLE;