VirtualBox

Changeset 6873 in vbox for trunk/src/VBox/Devices/PC


Ignore:
Timestamp:
Feb 9, 2008 4:51:15 PM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
28016
Message:

r=bird: Don't permit buffer overflows by long DMI strings in CFGM. Don't
return VERR_NO_MEMORY on overflow but something that's more descriptive.
Don't rely on undocument CFGM behaviour wrt to output variable preserving.
Restore the CFGMR3AreValuesValid input to a readable state.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/DevPcBios.cpp

    r6871 r6873  
    826826 * Construct the DMI table.
    827827 *
    828  * @param   table           pointer to DMI table.
    829  */
    830 #define STRCPY(p, s) do { memcpy (p, s, strlen(s)+1); p += strlen(s)+1; } while (0)
     828 * @returns VBox status code.
     829 * @param   pDevIns     The device instance.
     830 * @param   pTable      Where to create the DMI table.
     831 * @param   cbMax       The max size of the DMI table.
     832 * @param   pUuid       Pointer to the UUID to use if the DmiUuid
     833 *                      configuration string isn't present.
     834 * @param   pCfgHandle  The handle to our config node.
     835 */
     836static int pcbiosPlantDMITable(PPDMDEVINS pDevIns, uint8_t *pTable, unsigned cbMax, PRTUUID pUuid, PCFGMNODE pCfgHandle)
     837{
     838    char *pszStr = (char *)pTable;
     839    int iStrNr;
     840    int rc;
     841    char *pszDmiVendor, *pszDmiProduct, *pszDmiVersion, *pszDmiRelease, *pszDmiSerial, *pszDmiUuid, *pszDmiFamily;
     842
     843#define STRCPY(p, s) \
     844    do { \
     845        size_t _len = strlen(s) + 1; \
     846        if (pszStr + _len - (char *)pTable >= cbMax) \
     847            return PDMDevHlpVMSetError(pDevIns, VERR_TOO_MUCH_DATA, RT_SRC_POS, \
     848                    N_("DMI string too long (%zu): \"%s\""), _len, s); \
     849        memcpy(p, s, _len); \
     850        p += _len; \
     851    } while (0)
    831852#define READCFG(name, variable, default_value) \
    832853    do { \
     
    839860    } while (0)
    840861
    841 static int pcbiosPlantDMITable(PPDMDEVINS pDevIns, uint8_t *pTable, PRTUUID puuid, PCFGMNODE pCfgHandle)
    842 {
    843     char *pszStr = (char*)pTable;
    844     int iStrNr;
    845     int rc;
    846     char *pszDmiVendor, *pszDmiProduct, *pszDmiVersion, *pszDmiRelease, *pszDmiSerial, *pszDmiUuid = NULL, *pszDmiFamily;
    847862
    848863    READCFG("DmiVendor",  pszDmiVendor,  "innotek GmbH");
     
    852867    READCFG("DmiSerial",  pszDmiSerial,  "0");
    853868    rc = CFGMR3QueryStringAlloc(pCfgHandle, "DmiUuid", &pszDmiUuid);
    854     if (VBOX_FAILURE(rc) && rc != VERR_CFGM_VALUE_NOT_FOUND)
     869    if (rc == VERR_CFGM_VALUE_NOT_FOUND)
     870        pszDmiUuid = NULL;
     871    else if (VBOX_FAILURE(rc))
    855872        return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
    856873                                   N_("Configuration error: Querying \"DmiUuid\" as a string failed"));
     
    858875
    859876    PDMIBIOSINF pBIOSInf         = (PDMIBIOSINF)pszStr;
    860     pszStr                       = (char*)(pBIOSInf+1);
     877    pszStr                       = (char *)(pBIOSInf + 1);
    861878    iStrNr                       = 1;
    862879    pBIOSInf->header.u8Type      = 0; /* BIOS Information */
     
    889906
    890907    PDMISYSTEMINF pSystemInf     = (PDMISYSTEMINF)pszStr;
    891     pszStr                       = (char*)(pSystemInf+1);
     908    pszStr                       = (char *)(pSystemInf + 1);
    892909    iStrNr                       = 1;
    893910    pSystemInf->header.u8Type    = 1; /* System Information */
     
    913930        uuid.Gen.u16TimeMid = RT_H2BE_U16(uuid.Gen.u16TimeMid);
    914931        uuid.Gen.u16TimeHiAndVersion = RT_H2BE_U16(uuid.Gen.u16TimeHiAndVersion);
    915         puuid = &uuid;
    916     }
    917     memcpy(pSystemInf->au8Uuid, puuid, sizeof(RTUUID));
     932        pUuid = &uuid;
     933    }
     934    memcpy(pSystemInf->au8Uuid, pUuid, sizeof(RTUUID));
    918935
    919936    pSystemInf->u8WakeupType     = 6; /* Power Switch */
     
    922939    STRCPY(pszStr, pszDmiFamily);
    923940    *pszStr++                    = '\0';
     941
     942#undef STRCPY
     943#undef READCFG
     944
     945    if (pszStr - (char *)pTable > VBOX_DMI_TABLE_SIZE)
     946        return PDMDevHlpVMSetError(pDevIns, VERR_BUFFER_OVERFLOW, RT_SRC_POS,
     947                                   N_("DMI table too long (have=%d, max=%d)"),
     948                                   pszStr - (char *)pTable, VBOX_DMI_TABLE_SIZE);
    924949
    925950    MMR3HeapFree(pszDmiVendor);
     
    931956    MMR3HeapFree(pszDmiFamily);
    932957
    933     if (pszStr - (char*)pTable > VBOX_DMI_TABLE_SIZE)
    934         return PDMDevHlpVMSetError(pDevIns, VERR_NO_MEMORY, RT_SRC_POS,
    935                                    N_("DMI table too long (have=%d, max=%d)"), pszStr - (char*)pTable, VBOX_DMI_TABLE_SIZE);
    936 
    937958    return VINF_SUCCESS;
    938959}
    939 #undef STRCPY
    940960AssertCompile(VBOX_DMI_TABLE_ENTR == 2);
    941961
     
    10911111        pu8PcBiosBinary = g_abPcBiosBinary;
    10921112        cbPcBiosBinary  = g_cbPcBiosBinary;
    1093     } 
    1094     else 
     1113    }
     1114    else
    10951115    {
    10961116        pu8PcBiosBinary = pData->pu8PcBios;
     
    12661286     */
    12671287    if (!CFGMR3AreValuesValid(pCfgHandle,
    1268                               "BootDevice0\0BootDevice1\0BootDevice2\0BootDevice3\0"
    1269                               "RamSize\0HardDiskDevice\0FloppyDevice\0FadeIn\0FadeOut\0LogoTime\0LogoFile\0"
    1270                               "ShowBootMenu\0DelayBoot\0BiosRom\0LanBootRom\0PXEDebug\0UUID\0IOAPIC\0"
    1271                               "DmiVendor\0DmiProduct\0DmiVersion\0DmiSerial\0DmiUuid\0DmiFamily\0"))
     1288                              "BootDevice0\0"
     1289                              "BootDevice1\0"
     1290                              "BootDevice2\0"
     1291                              "BootDevice3\0"
     1292                              "RamSize\0"
     1293                              "HardDiskDevice\0"
     1294                              "FloppyDevice\0"
     1295                              "FadeIn\0"
     1296                              "FadeOut\0"
     1297                              "LogoTime\0"
     1298                              "LogoFile\0"
     1299                              "ShowBootMenu\0"
     1300                              "DelayBoot\0"
     1301                              "BiosRom\0"
     1302                              "LanBootRom\0"
     1303                              "PXEDebug\0"
     1304                              "UUID\0"
     1305                              "IOAPIC\0"
     1306                              "DmiVendor\0"
     1307                              "DmiProduct\0"
     1308                              "DmiVersion\0"
     1309                              "DmiSerial\0"
     1310                              "DmiUuid\0"
     1311                              "DmiFamily\0"))
    12721312        return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
    12731313                                N_("Invalid configuraton for  device pcbios device"));
     
    13331373    uuid.Gen.u16TimeMid = RT_H2BE_U16(uuid.Gen.u16TimeMid);
    13341374    uuid.Gen.u16TimeHiAndVersion = RT_H2BE_U16(uuid.Gen.u16TimeHiAndVersion);
    1335     rc = pcbiosPlantDMITable(pDevIns, pData->au8DMIPage, &uuid, pCfgHandle);
     1375    rc = pcbiosPlantDMITable(pDevIns, pData->au8DMIPage, 0x100 /* see below */, &uuid, pCfgHandle);
    13361376    if (VBOX_FAILURE(rc))
    13371377        return rc;
     
    14431483        pu8PcBiosBinary = g_abPcBiosBinary;
    14441484        cbPcBiosBinary  = g_cbPcBiosBinary;
    1445     } 
    1446     else 
     1485    }
     1486    else
    14471487    {
    14481488        pu8PcBiosBinary = pData->pu8PcBios;
     
    14611501                     ("cbPcBiosBinary=%#x\n", cbPcBiosBinary));
    14621502    cb = RT_MIN(cbPcBiosBinary, 128 * _1K); /* Effectively either 64 or 128K. */
    1463     rc = PDMDevHlpROMRegister(pDevIns, 0x00100000 - cb, cb, &pu8PcBiosBinary[cbPcBiosBinary - cb], 
     1503    rc = PDMDevHlpROMRegister(pDevIns, 0x00100000 - cb, cb, &pu8PcBiosBinary[cbPcBiosBinary - cb],
    14641504                              false /* fShadow */, "PC BIOS - 0xfffff");
    14651505    if (VBOX_FAILURE(rc))
    14661506        return rc;
    1467     rc = PDMDevHlpROMRegister(pDevIns, (uint32_t)-(int32_t)cbPcBiosBinary, cbPcBiosBinary, pu8PcBiosBinary, 
     1507    rc = PDMDevHlpROMRegister(pDevIns, (uint32_t)-(int32_t)cbPcBiosBinary, cbPcBiosBinary, pu8PcBiosBinary,
    14681508                              false /* fShadow */, "PC BIOS - 0xffffffff");
    14691509    if (VBOX_FAILURE(rc))
     
    16931733        pu8LanBootBinary = g_abNetBiosBinary;
    16941734        cbLanBootBinary  = g_cbNetBiosBinary;
    1695     } 
    1696     else 
     1735    }
     1736    else
    16971737    {
    16981738        pu8LanBootBinary = pData->pu8LanBoot;
     
    17061746     */
    17071747    if (pu8LanBootBinary)
    1708         rc = PDMDevHlpROMRegister(pDevIns, VBOX_LANBOOT_SEG << 4, cbLanBootBinary, pu8LanBootBinary, 
     1748        rc = PDMDevHlpROMRegister(pDevIns, VBOX_LANBOOT_SEG << 4, cbLanBootBinary, pu8LanBootBinary,
    17091749                                  true /* fShadow */, "Net Boot ROM");
    17101750
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette