VirtualBox

Changeset 85736 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Aug 12, 2020 9:11:37 PM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
139884
Message:

Main/HostUpdateImpl.cpp: Better (but completely untested) server response validation. Make sure we cannot throw exceptions before we call RTHttpFreeResponse. bugref:7983

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-server/HostUpdateImpl.cpp

    r85735 r85736  
    419419        return setErrorVrc(vrc, tr("%s: RTHttpGetBinary() failed: %Rrc"), __FUNCTION__, vrc);
    420420
    421     /** @todo this may throw and leak.   */
    422     RTCList<RTCString> lstHttpReply = RTCString((char *)pvResponse, (size_t)cbResponse).split(" ", RTCString::RemoveEmptyParts);
     421    /* Note! We can do nothing that might throw exceptions till we call RTHttpFreeResponse! */
     422
     423    /*
     424     * If url is platform=DARWIN_64BITS_GENERIC&version=6.0.12&branch=stable for example, the reply is:
     425     *      6.0.14<SPACE>https://download.virtualbox.org/virtualbox/6.0.14/VirtualBox-6.0.14-133895-OSX.dmg
     426     * If no update required, 'UPTODATE' is returned.
     427     */
     428    /* Parse out the two first words of the response, ignoring whatever follows: */
     429    const char *pchResponse = (const char *)pvResponse;
     430    while (cbResponse > 0 && *pchResponse == ' ')
     431        cbResponse--, pchResponse++;
     432
     433    char ch;
     434    const char *pchWord0 = pchResponse;
     435    while (cbResponse > 0 && (ch = *pchResponse) != ' ' && ch != '\0')
     436        cbResponse--, pchResponse++;
     437    size_t const cchWord0 = (size_t)(pchResponse - pchWord0);
     438
     439    while (cbResponse > 0 && *pchResponse == ' ')
     440        cbResponse--, pchResponse++;
     441    const char *pchWord1 = pchResponse;
     442    while (cbResponse > 0 && (ch = *pchResponse) != ' ' && ch != '\0')
     443        cbResponse--, pchResponse++;
     444    size_t const cchWord1 = (size_t)(pchResponse - pchWord1);
     445
     446    /* Decode the two word: */
     447    static char const s_szUpToDate[] = "UPTODATE";
     448    if (   cchWord0 == sizeof(s_szUpToDate) - 1
     449        && memcmp(pchWord0, s_szUpToDate, sizeof(s_szUpToDate) - 1) == 0)
     450    {
     451        m_updateNeeded = FALSE;
     452        rc = S_OK;
     453    }
     454    else
     455    {
     456        vrc = RTStrValidateEncodingEx(pchWord0, cchWord0, 0 /*fFlags*/);
     457        if (RT_SUCCESS(vrc))
     458            vrc = RTStrValidateEncodingEx(pchWord1, cchWord1, 0 /*fFlags*/);
     459        if (RT_SUCCESS(vrc))
     460        {
     461            /** @todo Any additional sanity checks we could perform here? */
     462            rc = m_updateVersion.assignEx(pchWord0, cchWord0);
     463            if (SUCCEEDED(rc))
     464            {
     465                rc = m_updateVersion.assignEx(pchWord1, cchWord1);
     466                if (SUCCEEDED(rc))
     467                    m_updateNeeded = TRUE;
     468            }
     469            LogRelFunc(("HTTP server reply = %.*s %.*s\n", cchWord0, pchWord0, cchWord1, pchWord1));
     470        }
     471        else
     472            rc = setErrorVrc(vrc, tr("Invalid server response: %Rrc (%.*Rhxs -- %.*Rhxs)"),
     473                             vrc, cchWord0, pchWord0, cchWord1, pchWord1);
     474    }
     475
    423476    RTHttpFreeResponse(pvResponse);
    424477
    425     // If url is platform=DARWIN_64BITS_GENERIC&version=6.0.12&branch=stable for example, the reply is:
    426     // reply[0] = 6.0.14
    427     // reply[1] = https://download.virtualbox.org/virtualbox/6.0.14/VirtualBox-6.0.14-133895-OSX.dmg
    428     // If no update required, 'UPTODATE' is returned.
    429     if (strcmp(lstHttpReply.at(0).c_str(), "UPTODATE") == 0)
    430     {
    431         m_updateNeeded = FALSE;
    432     }
    433     else
    434     {
    435         /** @todo r=bird: trusting the server reply too much here! */
    436         m_updateNeeded = TRUE;
    437         m_updateVersion = lstHttpReply.at(0).c_str();
    438         m_updateURL = lstHttpReply.at(1).c_str();
    439         LogRelFunc(("HTTP server reply = %s %s\n", lstHttpReply.at(0).c_str(), lstHttpReply.at(1).c_str()));
    440     }
    441 
    442     return S_OK;
     478    return rc;
    443479}
    444480
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