From ad88f982c095c12092cdecc3be8dd1e27387ea03 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 25 Jun 2019 06:12:13 +0000 Subject: [PATCH] Add some size checks when accessing Drives[], mostly needed when DOS_DRIVES is not set to 26, make size parsing not go outside the target array. Let's not try to assign a drive in the switchlist to a too high number. Don't access imagelist for drives >D when unmounting. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4239 --- include/bios_disk.h | 6 ++-- src/dos/dos_files.cpp | 2 +- src/dos/dos_programs.cpp | 73 +++++++++++++++++++++++++--------------- src/ints/bios_disk.cpp | 2 +- 4 files changed, 52 insertions(+), 31 deletions(-) diff --git a/include/bios_disk.h b/include/bios_disk.h index 25c0abf9..31537269 100644 --- a/include/bios_disk.h +++ b/include/bios_disk.h @@ -75,8 +75,10 @@ void incrementFDD(void); #define MAX_HDD_IMAGES 2 -extern imageDisk *imageDiskList[2 + MAX_HDD_IMAGES]; -extern imageDisk *diskSwap[20]; +#define MAX_DISK_IMAGES (2 + MAX_HDD_IMAGES) + +extern imageDisk *imageDiskList[MAX_DISK_IMAGES]; +extern imageDisk *diskSwap[MAX_SWAPPABLE_DISKS]; extern Bit32s swapPosition; extern Bit16u imgDTASeg; /* Real memory location of temporary DTA pointer for fat image disk access */ extern RealPt imgDTAPtr; /* Real memory location of temporary DTA pointer for fat image disk access */ diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index b78325ae..8d88361d 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -52,7 +52,7 @@ Bit8u DOS_GetDefaultDrive(void) { void DOS_SetDefaultDrive(Bit8u drive) { // if (drive<=DOS_DRIVES && ((drive<2) || Drives[drive])) DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).SetDrive(drive); - if (drive<=DOS_DRIVES && ((drive<2) || Drives[drive])) {dos.current_drive = drive; DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).SetDrive(drive);} + if (drive= DOS_DRIVES || i_drive < 0 || (Drives[i_drive] == NULL && imageDiskList[i_drive] == NULL)) + if (i_drive >= DOS_DRIVES || i_drive < 0) + return MSG_Get("PROGRAM_MOUNT_UMOUNT_NOT_MOUNTED"); + + if (i_drive < MAX_DISK_IMAGES && Drives[i_drive] == NULL && imageDiskList[i_drive] == NULL) + return MSG_Get("PROGRAM_MOUNT_UMOUNT_NOT_MOUNTED"); + + if (i_drive >= MAX_DISK_IMAGES && Drives[i_drive] == NULL) return MSG_Get("PROGRAM_MOUNT_UMOUNT_NOT_MOUNTED"); if (Drives[i_drive]) { @@ -82,7 +88,7 @@ static const char* UnmountHelper(char umount) { } - if (imageDiskList[i_drive]) { + if (i_drive < MAX_DISK_IMAGES && imageDiskList[i_drive]) { delete imageDiskList[i_drive]; imageDiskList[i_drive] = NULL; } @@ -245,23 +251,29 @@ public: } cmd->FindString("-size",str_size,true); - char number[20];const char * scan=str_size.c_str(); - Bitu index=0;Bitu count=0; + char number[21] = { 0 };const char * scan = str_size.c_str(); + Bitu index = 0;Bitu count = 0; /* Parse the str_size string */ - while (*scan) { + while (*scan && index < 20 && count < 4) { if (*scan==',') { - number[index]=0;sizes[count++]=atoi(number); - index=0; - } else number[index++]=*scan; + number[index] = 0; + sizes[count++] = atoi(number); + index = 0; + } else number[index++] = *scan; scan++; } - number[index]=0;sizes[count++]=atoi(number); + if (count < 4) { + number[index] = 0; //always goes correct as index is max 20 at this point. + sizes[count] = atoi(number); + } // get the drive letter cmd->FindCommand(1,temp_line); if ((temp_line.size() > 2) || ((temp_line.size()>1) && (temp_line[1]!=':'))) goto showusage; - drive=toupper(temp_line[0]); - if (!isalpha(drive)) goto showusage; + int i_drive = toupper(temp_line[0]); + if (!isalpha(i_drive)) goto showusage; + if ((i_drive - 'A') >= DOS_DRIVES || (i_drive-'A') < 0 ) goto showusage; + drive = static_cast(i_drive); if (!cmd->FindCommand(2,temp_line)) goto showusage; if (!temp_line.size()) goto showusage; @@ -407,11 +419,11 @@ public: std::string base = ldp->getBasedir(); Bit8u o_error = 0; newdrive = new Overlay_Drive(base.c_str(),temp_line.c_str(),sizes[0],bit8size,sizes[2],sizes[3],mediaid,o_error); - //Erase old drive on succes + //Erase old drive on success if (newdrive) { if (o_error) { if (o_error == 1) WriteOut("No mixing of relative and absolute paths. Overlay failed."); - else if (o_error == 2) WriteOut("overlay directory can not be the same as underlying filesystem."); + else if (o_error == 2) WriteOut("overlay directory can not be the same as underlying file system."); else WriteOut("Something went wrong"); delete newdrive; return; @@ -693,7 +705,10 @@ public: i++; continue; } - + + if ( i >= MAX_SWAPPABLE_DISKS ) { + return; //TODO give a warning. + } WriteOut(MSG_Get("PROGRAM_BOOT_IMAGE_OPEN"), temp_line.c_str()); Bit32u rombytesize; FILE *usefile = getFSFile(temp_line.c_str(), &floppysize, &rombytesize); @@ -1190,18 +1205,21 @@ public: if ((type=="hdd") && (str_size.size()==0)) { imgsizedetect=true; } else { - char number[20]; - const char * scan=str_size.c_str(); - Bitu index=0;Bitu count=0; - - while (*scan) { + char number[21] = { 0 };const char * scan = str_size.c_str(); + Bitu index = 0;Bitu count = 0; + /* Parse the str_size string */ + while (*scan && index < 20 && count < 4) { if (*scan==',') { - number[index]=0;sizes[count++]=atoi(number); - index=0; - } else number[index++]=*scan; + number[index] = 0; + sizes[count++] = atoi(number); + index = 0; + } else number[index++] = *scan; scan++; } - number[index]=0;sizes[count++]=atoi(number); + if (count < 4) { + number[index] = 0; //always goes correct as index is max 20 at this point. + sizes[count] = atoi(number); + } } if(fstype=="fat" || fstype=="iso") { @@ -1210,11 +1228,12 @@ public: WriteOut_NoParsing(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_DRIVE")); return; } - drive=toupper(temp_line[0]); - if (!isalpha(drive)) { + int i_drive = toupper(temp_line[0]); + if (!isalpha(drive) || (i_drive - 'A') >= DOS_DRIVES || (i_drive - 'A') <0) { WriteOut_NoParsing(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_DRIVE")); return; } + drive = static_cast(i_drive); } else if (fstype=="none") { cmd->FindCommand(1,temp_line); if ((temp_line.size() > 1) || (!isdigit(temp_line[0]))) { @@ -1222,7 +1241,7 @@ public: return; } drive=temp_line[0]; - if ((drive<'0') || (drive>3+'0')) { + if ((drive<'0') || (drive>=(MAX_DISK_IMAGES+'0'))) { WriteOut_NoParsing(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY2")); return; } @@ -1452,7 +1471,7 @@ public: WriteOut(MSG_Get("PROGRAM_IMGMOUNT_MOUNT_NUMBER"),drive-'0',temp_line.c_str()); } - // check if volume label is given. becareful for cdrom + // check if volume label is given. be careful for cdrom //if (cmd->FindString("-label",label,true)) newdrive->dirCache.SetLabel(label.c_str()); return; } diff --git a/src/ints/bios_disk.cpp b/src/ints/bios_disk.cpp index f3eaab78..7edc771c 100644 --- a/src/ints/bios_disk.cpp +++ b/src/ints/bios_disk.cpp @@ -27,7 +27,7 @@ #include "../dos/drives.h" #include "mapper.h" -#define MAX_DISK_IMAGES 4 + diskGeo DiskGeometryList[] = { { 160, 8, 1, 40, 0},