Skip to content

Commit c8f7357

Browse files
committed
bus/nscsi/cd: Fix ZuluSCSI/BlueSCSI toolbox use-after-free in
update_directory() AI disclosure: gpt-5.6-sol was used as a research and debugging tool.
1 parent ec7dfe9 commit c8f7357

2 files changed

Lines changed: 12 additions & 7 deletions

File tree

src/devices/bus/nscsi/cd.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -297,9 +297,7 @@ void nscsi_cdrom_device::update_directory()
297297

298298
while ((ourEntry = directory->read()) != nullptr)
299299
{
300-
// FIXME: use-after-free
301-
// the directory entry's name is not valid after a subsequent call to read()
302-
m_directory.push_back(*ourEntry);
300+
m_directory.push_back({ ourEntry->name, ourEntry->type, ourEntry->size });
303301

304302
// API version 0 has a hard cap of 100 files
305303
if (m_directory.size() >= 99)
@@ -970,13 +968,13 @@ void nscsi_cdrom_device::scsi_command()
970968
m_scsi_cmdbuf[pos] = index;
971969
m_scsi_cmdbuf[pos + 1] = m_directory[index].type != osd::directory::entry::entry_type::DIR;
972970
// There's a guaranteed null terminator one byte after the name field
973-
strncpy(reinterpret_cast<char *>(&m_scsi_cmdbuf[pos + 2]), m_directory[index].name, 31);
971+
strncpy(reinterpret_cast<char *>(&m_scsi_cmdbuf[pos + 2]), m_directory[index].name.c_str(), 31);
974972
m_scsi_cmdbuf[pos + 36] = (m_directory[index].size >> 24) & 0xff;
975973
m_scsi_cmdbuf[pos + 37] = (m_directory[index].size >> 16) & 0xff;
976974
m_scsi_cmdbuf[pos + 38] = (m_directory[index].size >> 8) & 0xff;
977975
m_scsi_cmdbuf[pos + 39] = m_directory[index].size & 0xff;
978976

979-
LOG("%02d: %s %08x\n", index, m_directory[index].name, (uint32_t)m_directory[index].size);
977+
LOG("%02d: %s %08x\n", index, m_directory[index].name.c_str(), (uint32_t)m_directory[index].size);
980978

981979
index++;
982980
pos += 40;
@@ -1002,7 +1000,7 @@ void nscsi_cdrom_device::scsi_command()
10021000

10031001
uint32_t offset = m_scsi_cmdbuf[2] << 24 | m_scsi_cmdbuf[3] << 16 | m_scsi_cmdbuf[4] << 8 | m_scsi_cmdbuf[5];
10041002
uint32_t blocks = m_scsi_cmdbuf[6];
1005-
LOG("TOOLBOX_GET_FILE: file # %d (%s), offset %08x, blocks %d\n", m_scsi_cmdbuf[1], m_directory[m_scsi_cmdbuf[1]].name, offset, blocks);
1003+
LOG("TOOLBOX_GET_FILE: file # %d (%s), offset %08x, blocks %d\n", m_scsi_cmdbuf[1], m_directory[m_scsi_cmdbuf[1]].name.c_str(), offset, blocks);
10061004
if (blocks == 0)
10071005
{
10081006
blocks = 1;

src/devices/bus/nscsi/cd.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ class nscsi_cdrom_device : public nscsi_full_device
5252
bool m_removal_prevented;
5353

5454
private:
55+
struct toolbox_directory_entry
56+
{
57+
std::string name;
58+
osd::directory::entry::entry_type type;
59+
uint64_t size;
60+
};
61+
5562
static constexpr uint32_t bytes_per_sector = 2048;
5663

5764
u32 sequence_counter;
@@ -74,7 +81,7 @@ class nscsi_cdrom_device : public nscsi_full_device
7481
uint32_t m_write_offset;
7582
bool m_write_is_setup;
7683
std::string m_write_path;
77-
std::vector<osd::directory::entry> m_directory;
84+
std::vector<toolbox_directory_entry> m_directory;
7885
std::vector<uint8_t> m_xfer_buffer;
7986
};
8087

0 commit comments

Comments
 (0)