VirtualBox

Changeset 79677 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jul 10, 2019 3:45:05 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
131994
Message:

Runtime/r3/xml.cpp: Introduce methods which limit the size of element and attribute values when querying them. Just for sanitizing, not that the buffer size is actually limited.
Main/Appliance+ExtPack: Use size checks to play safe with XML sata.

Location:
trunk/src/VBox
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-all/ExtPackUtil.cpp

    r76553 r79677  
    113113
    114114    RTCString strFormatVersion;
    115     if (!pVBoxExtPackElm->getAttributeValue("version", strFormatVersion))
     115    if (!pVBoxExtPackElm->getAttributeValueN("version", strFormatVersion, RT_XML_ATTR_TINY))
    116116        return new RTCString("Missing format version");
    117117    if (!strFormatVersion.equals("1.0"))
     
    124124    if (!pNameElm)
    125125        return new RTCString("The 'Name' element is missing");
    126     const char *pszName = pNameElm->getValue();
     126    const char *pszName = pNameElm->getValueN(RT_XML_CONTENT_SMALL);
    127127    if (!VBoxExtPackIsValidName(pszName))
    128128        return &(new RTCString("Invalid name: "))->append(pszName);
     
    131131    if (!pDescElm)
    132132        return new RTCString("The 'Description' element is missing");
    133     const char *pszDesc = pDescElm->getValue();
     133    const char *pszDesc = pDescElm->getValueN(RT_XML_CONTENT_LARGE);
    134134    if (!pszDesc || *pszDesc == '\0')
    135135        return new RTCString("The 'Description' element is empty");
     
    140140    if (!pVersionElm)
    141141        return new RTCString("The 'Version' element is missing");
    142     const char *pszVersion = pVersionElm->getValue();
     142    const char *pszVersion = pVersionElm->getValueN(RT_XML_CONTENT_SMALL);
    143143    if (!pszVersion || *pszVersion == '\0')
    144144        return new RTCString("The 'Version' element is empty");
     
    151151
    152152    const char *pszEdition;
    153     if (!pVersionElm->getAttributeValue("edition", pszEdition))
     153    if (!pVersionElm->getAttributeValueN("edition", pszEdition, RT_XML_ATTR_TINY))
    154154        pszEdition = "";
    155155    if (!VBoxExtPackIsValidEditionString(pszEdition))
     
    159159    if (!pMainModuleElm)
    160160        return new RTCString("The 'MainModule' element is missing");
    161     const char *pszMainModule = pMainModuleElm->getValue();
     161    const char *pszMainModule = pMainModuleElm->getValueN(RT_XML_CONTENT_SMALL);
    162162    if (!pszMainModule || *pszMainModule == '\0')
    163163        return new RTCString("The 'MainModule' element is empty");
     
    173173    if (pMainVMModuleElm)
    174174    {
    175         pszMainVMModule = pMainVMModuleElm->getValue();
     175        pszMainVMModule = pMainVMModuleElm->getValueN(RT_XML_CONTENT_SMALL);
    176176        if (!pszMainVMModule || *pszMainVMModule == '\0')
    177177            pszMainVMModule = NULL;
     
    188188    if (pVrdeModuleElm)
    189189    {
    190         pszVrdeModule = pVrdeModuleElm->getValue();
     190        pszVrdeModule = pVrdeModuleElm->getValueN(RT_XML_CONTENT_SMALL);
    191191        if (!pszVrdeModule || *pszVrdeModule == '\0')
    192192            pszVrdeModule = NULL;
     
    282282     * Hand the xml doc over to the common code.
    283283     */
    284     return vboxExtPackLoadDescFromDoc(&Doc, a_pExtPackDesc);
     284    try
     285    {
     286        return vboxExtPackLoadDescFromDoc(&Doc, a_pExtPackDesc);
     287    }
     288    catch (RTCError &rXcpt)      // includes all XML exceptions
     289    {
     290        return new RTCString(rXcpt.what());
     291    }
    285292}
    286293
     
    358365     */
    359366    if (RT_SUCCESS(rc))
    360         pstrErr = vboxExtPackLoadDescFromDoc(&Doc, a_pExtPackDesc);
     367        try
     368        {
     369            pstrErr = vboxExtPackLoadDescFromDoc(&Doc, a_pExtPackDesc);
     370        }
     371        catch (RTCError &rXcpt)      // includes all XML exceptions
     372        {
     373            return new RTCString(rXcpt.what());
     374        }
    361375
    362376    return pstrErr;
  • trunk/src/VBox/Main/xml/ovfreader.cpp

    r78604 r79677  
    107107    if ((pTypeAttr = pRootElem->findAttribute("lang", "xml")))
    108108    {
    109         pcszTypeAttr = pTypeAttr->getValue();
     109        pcszTypeAttr = pTypeAttr->getValueN(RT_XML_ATTR_TINY);
    110110        m_envelopeData.lang = pcszTypeAttr;
    111111    }
     
    148148        const char *pcszElemName = pElem->getName();
    149149        const xml::AttributeNode *pTypeAttr = pElem->findAttribute("type");
    150         const char *pcszTypeAttr = pTypeAttr ? pTypeAttr->getValue() : "";
     150        const char *pcszTypeAttr = pTypeAttr ? pTypeAttr->getValueN(RT_XML_ATTR_TINY) : "";
    151151
    152152        if (    !strcmp(pcszElemName, "DiskSection")
     
    226226        const char *pcszDiskId;
    227227        const char *pcszFormat;
    228         if (!pelmDisk->getAttributeValue("diskId", pcszDiskId))
     228        if (!pelmDisk->getAttributeValueN("diskId", pcszDiskId, RT_XML_ATTR_TINY))
    229229            pcszBad = "diskId";
    230         else if (!pelmDisk->getAttributeValue("format", pcszFormat))
     230        else if (!pelmDisk->getAttributeValueN("format", pcszFormat, RT_XML_ATTR_SMALL))
    231231            pcszBad = "format";
    232232        else if (!pelmDisk->getAttributeValue("capacity", d.iCapacity))
     
    242242
    243243            // optional vbox:uuid attribute (if OVF was exported by VirtualBox != 3.2)
    244             pelmDisk->getAttributeValue("uuid", d.uuidVBox, "vbox");
     244            pelmDisk->getAttributeValueN("uuid", d.uuidVBox, RT_XML_ATTR_TINY, "vbox");
    245245
    246246            const char *pcszFileRef;
    247             if (pelmDisk->getAttributeValue("fileRef", pcszFileRef)) // optional
     247            if (pelmDisk->getAttributeValueN("fileRef", pcszFileRef, RT_XML_ATTR_SMALL)) // optional
    248248            {
    249249                // look up corresponding /References/File nodes (list built above)
     
    257257                    const char *pcszBadInFile = NULL;
    258258                    const char *pcszHref;
    259                     if (!pFileElem->getAttributeValue("href", pcszHref))
     259                    if (!pFileElem->getAttributeValueN("href", pcszHref, RT_XML_ATTR_SMALL))
    260260                        pcszBadInFile = "href";
    261261                    else if (!pFileElem->getAttributeValue("size", d.iSize))
     
    267267                    d.iChunkSize = -1;       // optional
    268268                    const char *pcszCompression;
    269                     if (pFileElem->getAttributeValue("compression", pcszCompression))
     269                    if (pFileElem->getAttributeValueN("compression", pcszCompression, RT_XML_ATTR_TINY))
    270270                        d.strCompression = pcszCompression;
    271271
     
    350350    const xml::AttributeNode *pIdAttr = pelmVirtualSystem->findAttribute("id");
    351351    if (pIdAttr)
    352         vsys.strName = pIdAttr->getValue();
     352        vsys.strName = pIdAttr->getValueN(RT_XML_ATTR_SMALL);
    353353
    354354    xml::NodesLoop loop(*pelmVirtualSystem);      // all child elements
     
    362362            const xml::AttributeNode *pTypeAttr = pelmThis->findAttribute("type");
    363363            if (pTypeAttr)
    364                 pcszTypeAttr = pTypeAttr->getValue();
     364                pcszTypeAttr = pTypeAttr->getValueN(RT_XML_ATTR_TINY);
    365365            else
    366366                throw OVFLogicError(N_("Error reading \"%s\": element \"Section\" has no \"type\" attribute, line %d"),
     
    380380            const xml::ElementNode *pelmLicense;
    381381            if ((pelmLicense = pelmThis->findChildElement("License")))
    382                 vsys.strLicenseText = pelmLicense->getValue();
     382                vsys.strLicenseText = pelmLicense->getValueN(RT_XML_CONTENT_LARGE);
    383383        }
    384384        if (    !strcmp(pcszElemName, "ProductSection")
     
    396396            const xml::ElementNode *pelmProduct;
    397397            if ((pelmProduct = pelmThis->findChildElement("Product")))
    398                 vsys.strProduct = pelmProduct->getValue();
     398                vsys.strProduct = pelmProduct->getValueN(RT_XML_CONTENT_SMALL);
    399399            const xml::ElementNode *pelmVendor;
    400400            if ((pelmVendor = pelmThis->findChildElement("Vendor")))
    401                 vsys.strVendor = pelmVendor->getValue();
     401                vsys.strVendor = pelmVendor->getValueN(RT_XML_CONTENT_SMALL);
    402402            const xml::ElementNode *pelmVersion;
    403403            if ((pelmVersion = pelmThis->findChildElement("Version")))
    404                 vsys.strVersion = pelmVersion->getValue();
     404                vsys.strVersion = pelmVersion->getValueN(RT_XML_CONTENT_SMALL);
    405405            const xml::ElementNode *pelmProductUrl;
    406406            if ((pelmProductUrl = pelmThis->findChildElement("ProductUrl")))
    407                 vsys.strProductUrl = pelmProductUrl->getValue();
     407                vsys.strProductUrl = pelmProductUrl->getValueN(RT_XML_CONTENT_SMALL);
    408408            const xml::ElementNode *pelmVendorUrl;
    409409            if ((pelmVendorUrl = pelmThis->findChildElement("VendorUrl")))
    410                 vsys.strVendorUrl = pelmVendorUrl->getValue();
     410                vsys.strVendorUrl = pelmVendorUrl->getValueN(RT_XML_CONTENT_SMALL);
    411411        }
    412412        else if (    !strcmp(pcszElemName, "VirtualHardwareSection")
     
    425425                </System>*/
    426426                if ((pelmVirtualSystemType = pelmSystem->findChildElement("VirtualSystemType")))
    427                     vsys.strVirtualSystemType = pelmVirtualSystemType->getValue();
     427                    vsys.strVirtualSystemType = pelmVirtualSystemType->getValueN(RT_XML_CONTENT_SMALL);
    428428            }
    429429
     
    792792            const xml::ElementNode *pelmCIMOSDescription;
    793793            if ((pelmCIMOSDescription = pelmThis->findChildElement("Description")))
    794                 vsys.strCimosDesc = pelmCIMOSDescription->getValue();
     794                vsys.strCimosDesc = pelmCIMOSDescription->getValueN(RT_XML_CONTENT_SMALL);
    795795
    796796            const xml::ElementNode *pelmVBoxOSType;
    797797            if ((pelmVBoxOSType = pelmThis->findChildElementNS("vbox",            // namespace
    798798                                                               "OSType")))        // element name
    799                 vsys.strTypeVBox = pelmVBoxOSType->getValue();
     799                vsys.strTypeVBox = pelmVBoxOSType->getValueN(RT_XML_CONTENT_SMALL);
    800800        }
    801801        else if (    (!strcmp(pcszElemName, "AnnotationSection"))
     
    805805            const xml::ElementNode *pelmAnnotation;
    806806            if ((pelmAnnotation = pelmThis->findChildElement("Annotation")))
    807                 vsys.strDescription = pelmAnnotation->getValue();
     807                vsys.strDescription = pelmAnnotation->getValueN(RT_XML_CONTENT_SMALL);
    808808        }
    809809    }
     
    818818        const char *pcszItemChildName = pelmItemChild->getName();
    819819        if (!strcmp(pcszItemChildName, "Description"))
    820             strDescription = pelmItemChild->getValue();
     820            strDescription = pelmItemChild->getValueN(RT_XML_CONTENT_SMALL);
    821821        else if (!strcmp(pcszItemChildName, "Caption"))
    822             strCaption = pelmItemChild->getValue();
     822            strCaption = pelmItemChild->getValueN(RT_XML_CONTENT_SMALL);
    823823        else if (!strcmp(pcszItemChildName, "ElementName"))
    824             strElementName = pelmItemChild->getValue();
     824            strElementName = pelmItemChild->getValueN(RT_XML_CONTENT_SMALL);
    825825        else if (   !strcmp(pcszItemChildName, "InstanceID")
    826826                 || !strcmp(pcszItemChildName, "InstanceId") )
    827827            pelmItemChild->copyValue(ulInstanceID);
    828828        else if (!strcmp(pcszItemChildName, "HostResource"))
    829             strHostResource = pelmItemChild->getValue();
     829            strHostResource = pelmItemChild->getValueN(RT_XML_CONTENT_SMALL);
    830830        else if (!strcmp(pcszItemChildName, "ResourceType"))
    831831        {
     
    835835            fResourceRequired = true;
    836836            const char *pcszAttValue;
    837             if (item->getAttributeValue("required", pcszAttValue))
     837            if (item->getAttributeValueN("required", pcszAttValue, RT_XML_ATTR_TINY))
    838838            {
    839839                if (!strcmp(pcszAttValue, "false"))
     
    842842        }
    843843        else if (!strcmp(pcszItemChildName, "OtherResourceType"))
    844             strOtherResourceType = pelmItemChild->getValue();
     844            strOtherResourceType = pelmItemChild->getValueN(RT_XML_CONTENT_SMALL);
    845845        else if (!strcmp(pcszItemChildName, "ResourceSubType"))
    846             strResourceSubType = pelmItemChild->getValue();
     846            strResourceSubType = pelmItemChild->getValueN(RT_XML_CONTENT_SMALL);
    847847        else if (!strcmp(pcszItemChildName, "AutomaticAllocation"))
    848             fAutomaticAllocation = (!strcmp(pelmItemChild->getValue(), "true")) ? true : false;
     848            fAutomaticAllocation = (!strcmp(pelmItemChild->getValueN(RT_XML_CONTENT_SMALL), "true")) ? true : false;
    849849        else if (!strcmp(pcszItemChildName, "AutomaticDeallocation"))
    850             fAutomaticDeallocation = (!strcmp(pelmItemChild->getValue(), "true")) ? true : false;
     850            fAutomaticDeallocation = (!strcmp(pelmItemChild->getValueN(RT_XML_CONTENT_SMALL), "true")) ? true : false;
    851851        else if (!strcmp(pcszItemChildName, "Parent"))
    852852            pelmItemChild->copyValue(ulParent);
    853853        else if (!strcmp(pcszItemChildName, "Connection"))
    854             strConnection = pelmItemChild->getValue();
     854            strConnection = pelmItemChild->getValueN(RT_XML_CONTENT_SMALL);
    855855        else if (!strcmp(pcszItemChildName, "Address"))
    856856        {
    857             strAddress = pelmItemChild->getValue();
     857            strAddress = pelmItemChild->getValueN(RT_XML_CONTENT_SMALL);
    858858            pelmItemChild->copyValue(lAddress);
    859859        }
    860860        else if (!strcmp(pcszItemChildName, "AddressOnParent"))
    861             strAddressOnParent = pelmItemChild->getValue();
     861            strAddressOnParent = pelmItemChild->getValueN(RT_XML_CONTENT_SMALL);
    862862        else if (!strcmp(pcszItemChildName, "AllocationUnits"))
    863             strAllocationUnits = pelmItemChild->getValue();
     863            strAllocationUnits = pelmItemChild->getValueN(RT_XML_CONTENT_SMALL);
    864864        else if (!strcmp(pcszItemChildName, "VirtualQuantity"))
    865865            pelmItemChild->copyValue(ullVirtualQuantity);
     
    871871            pelmItemChild->copyValue(ullWeight);
    872872        else if (!strcmp(pcszItemChildName, "ConsumerVisibility"))
    873             strConsumerVisibility = pelmItemChild->getValue();
     873            strConsumerVisibility = pelmItemChild->getValueN(RT_XML_CONTENT_SMALL);
    874874        else if (!strcmp(pcszItemChildName, "MappingBehavior"))
    875             strMappingBehavior = pelmItemChild->getValue();
     875            strMappingBehavior = pelmItemChild->getValueN(RT_XML_CONTENT_SMALL);
    876876        else if (!strcmp(pcszItemChildName, "PoolID"))
    877             strPoolID = pelmItemChild->getValue();
     877            strPoolID = pelmItemChild->getValueN(RT_XML_CONTENT_SMALL);
    878878        else if (!strcmp(pcszItemChildName, "BusNumber"))
    879879            pelmItemChild->copyValue(ulBusNumber);
     
    921921        const char *pcszItemChildName = pelmItemChild->getName();
    922922        if (!strcmp(pcszItemChildName, "HostExtentName"))
    923             strHostExtentName = pelmItemChild->getValue();
     923            strHostExtentName = pelmItemChild->getValueN(RT_XML_CONTENT_SMALL);
    924924        else if (!strcmp(pcszItemChildName, "OtherHostExtentNameFormat"))
    925             strOtherHostExtentNameFormat = pelmItemChild->getValue();
     925            strOtherHostExtentNameFormat = pelmItemChild->getValueN(RT_XML_CONTENT_SMALL);
    926926        else if (!strcmp(pcszItemChildName, "OtherHostExtentNameNamespace"))
    927             strOtherHostExtentNameNamespace = pelmItemChild->getValue();
     927            strOtherHostExtentNameNamespace = pelmItemChild->getValueN(RT_XML_CONTENT_SMALL);
    928928        else if (!strcmp(pcszItemChildName, "VirtualQuantityUnits"))
    929             strVirtualQuantityUnits = pelmItemChild->getValue();
     929            strVirtualQuantityUnits = pelmItemChild->getValueN(RT_XML_CONTENT_SMALL);
    930930        else if (!strcmp(pcszItemChildName, "Access"))
    931931        {
  • trunk/src/VBox/Runtime/r3/xml.cpp

    r76553 r79677  
    565565
    566566/**
     567 * Returns the value of a node. If this node is an attribute, returns
     568 * the attribute value; if this node is an element, then this returns
     569 * the element text content.
     570 * @return
     571 * @param   cchValueLimit   If the length of the returned value exceeds this
     572 *                          limit a EIPRTFailure exception will be thrown.
     573 */
     574const char *Node::getValueN(size_t cchValueLimit) const
     575{
     576    if (   m_pLibAttr
     577        && m_pLibAttr->children
     578        )
     579    {
     580        // libxml hides attribute values in another node created as a
     581        // single child of the attribute node, and it's in the content field
     582        AssertStmt(strlen((const char *)m_pLibAttr->children->content) <= cchValueLimit, throw EIPRTFailure(VERR_BUFFER_OVERFLOW, "Attribute '%s' exceeds limit of %zu bytes", m_pcszName, cchValueLimit));
     583        return (const char *)m_pLibAttr->children->content;
     584    }
     585
     586    if (   m_pLibNode
     587        && m_pLibNode->children)
     588    {
     589        AssertStmt(strlen((const char *)m_pLibNode->children->content) <= cchValueLimit, throw EIPRTFailure(VERR_BUFFER_OVERFLOW, "Element '%s' exceeds limit of %zu bytes", m_pcszName, cchValueLimit));
     590        return (const char *)m_pLibNode->children->content;
     591    }
     592
     593    return NULL;
     594}
     595
     596/**
    567597 * Copies the value of a node into the given integer variable.
    568598 * Returns TRUE only if a value was found and was actually an
     
    11521182            return true;
    11531183        }
     1184    }
     1185
     1186    return false;
     1187}
     1188
     1189/**
     1190 * Convenience method which attempts to find the attribute with the given
     1191 * name and returns its value as a string.
     1192 *
     1193 * @param   pcszMatch       Name of attribute to find.
     1194 * @param   ppcsz           Where to return the attribute.
     1195 * @param   cchValueLimit   If the length of the returned value exceeds this
     1196 *                          limit a EIPRTFailure exception will be thrown.
     1197 * @param   pcszNamespace   The attribute name space prefix or NULL.
     1198 * @returns Boolean success indicator.
     1199 */
     1200bool ElementNode::getAttributeValueN(const char *pcszMatch, const char **ppcsz, size_t cchValueLimit, const char *pcszNamespace /*= NULL*/) const
     1201{
     1202    const AttributeNode *pAttr = findAttribute(pcszMatch, pcszNamespace);
     1203    if (pAttr)
     1204    {
     1205        *ppcsz = pAttr->getValueN(cchValueLimit);
     1206        return true;
     1207    }
     1208    return false;
     1209}
     1210
     1211/**
     1212 * Convenience method which attempts to find the attribute with the given
     1213 * name and returns its value as a string.
     1214 *
     1215 * @param   pcszMatch       Name of attribute to find.
     1216 * @param   pStr            Pointer to the string object that should receive the
     1217 *                          attribute value.
     1218 * @param   cchValueLimit   If the length of the returned value exceeds this
     1219 *                          limit a EIPRTFailure exception will be thrown.
     1220 * @param   pcszNamespace   The attribute name space prefix or NULL.
     1221 * @returns Boolean success indicator.
     1222 *
     1223 * @throws  Whatever the string class may throw on assignment.
     1224 */
     1225bool ElementNode::getAttributeValueN(const char *pcszMatch, RTCString *pStr, size_t cchValueLimit, const char *pcszNamespace /*= NULL*/) const
     1226{
     1227    const AttributeNode *pAttr = findAttribute(pcszMatch, pcszNamespace);
     1228    if (pAttr)
     1229    {
     1230        *pStr = pAttr->getValueN(cchValueLimit);
     1231        return true;
     1232    }
     1233
     1234    return false;
     1235}
     1236
     1237/**
     1238 * Like getAttributeValue (ministring variant), but makes sure that all backslashes
     1239 * are converted to forward slashes.
     1240 *
     1241 * @param   pcszMatch       Name of attribute to find.
     1242 * @param   pStr            Pointer to the string object that should
     1243 *                          receive the attribute path value.
     1244 * @param   cchValueLimit   If the length of the returned value exceeds this
     1245 *                          limit a EIPRTFailure exception will be thrown.
     1246 * @param   pcszNamespace   The attribute name space prefix or NULL.
     1247 * @returns Boolean success indicator.
     1248 */
     1249bool ElementNode::getAttributeValuePathN(const char *pcszMatch, RTCString *pStr, size_t cchValueLimit, const char *pcszNamespace /*= NULL*/) const
     1250{
     1251    if (getAttributeValueN(pcszMatch, pStr, cchValueLimit, pcszNamespace))
     1252    {
     1253        pStr->findReplace('\\', '/');
     1254        return true;
    11541255    }
    11551256
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