VirtualBox

Changeset 93891 in vbox


Ignore:
Timestamp:
Feb 22, 2022 6:08:39 PM (3 years ago)
Author:
vboxsync
Message:

Main: Guest Properties: improved property name and value validation, bugref:10185.

This commit also prevents guest properties loss if they were set while VM was running.

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/HostServices/GuestPropertySvc.h

    r93115 r93891  
    6666#define GUEST_PROP_F_ALLFLAGS         (GUEST_PROP_F_TRANSIENT | GUEST_PROP_F_READONLY | GUEST_PROP_F_TRANSRESET)
    6767/** @} */
     68
     69/**
     70 * Check that a string fits our criteria for a property name.
     71 *
     72 * @returns IPRT status code
     73 * @param   pszName   the string to check, must be valid Utf8
     74 * @param   cbName    the number of bytes @a pszName points to, including the terminating character.
     75 */
     76DECLINLINE(int) GuestPropValidateName(const char *pszName, uint32_t cbName)
     77{
     78    /* Property name is expected to be at least 1 charecter long plus terminating character. */
     79    AssertReturn(cbName >= 2, VERR_INVALID_PARAMETER);
     80    AssertReturn(cbName < GUEST_PROP_MAX_NAME_LEN, VERR_INVALID_PARAMETER);
     81
     82    AssertPtrReturn(pszName, VERR_INVALID_POINTER);
     83
     84    AssertReturn(memchr(pszName, '*', cbName) == NULL, VERR_INVALID_PARAMETER);
     85    AssertReturn(memchr(pszName, '?', cbName) == NULL, VERR_INVALID_PARAMETER);
     86    AssertReturn(memchr(pszName, '|', cbName) == NULL, VERR_INVALID_PARAMETER);
     87
     88    return VINF_SUCCESS;
     89}
     90
     91/**
     92 * Check a string fits our criteria for the value of a guest property.
     93 *
     94 * @returns IPRT status code
     95 * @param   pszValue  the string to check, must be valid Utf8
     96 * @param   cbValue   the length in bytes of @a pszValue, including the
     97 *                    terminator
     98 * @thread  HGCM
     99 */
     100DECLINLINE(int) GuestPropValidateValue(const char *pszValue, uint32_t cbValue)
     101{
     102    AssertPtrReturn(pszValue, VERR_INVALID_POINTER);
     103
     104    /* Zero-length values are possible, however buffer should contain terminating character at least. */
     105    AssertReturn(cbValue > 0, VERR_INVALID_PARAMETER);
     106    AssertReturn(cbValue < GUEST_PROP_MAX_VALUE_LEN, VERR_INVALID_PARAMETER);
     107
     108    return VINF_SUCCESS;
     109}
    68110
    69111/**
  • trunk/src/VBox/HostServices/GuestProperties/VBoxGuestPropSvc.cpp

    r93115 r93891  
    416416    static DECLCALLBACK(int) reqThreadFn(RTTHREAD ThreadSelf, void *pvUser);
    417417    uint64_t getCurrentTimestamp(void);
    418     int validateName(const char *pszName, uint32_t cbName);
    419     int validateValue(const char *pszValue, uint32_t cbValue);
    420418    int setPropertyBlock(uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
    421419    int getProperty(uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
     
    471469    this->mPrevTimestamp = u64NanoTS;
    472470    return u64NanoTS;
    473 }
    474 
    475 /**
    476  * Check that a string fits our criteria for a property name.
    477  *
    478  * @returns IPRT status code
    479  * @param   pszName   the string to check, must be valid Utf8
    480  * @param   cbName    the number of bytes @a pszName points to, including the
    481  *                    terminating '\0'
    482  * @thread  HGCM
    483  */
    484 int Service::validateName(const char *pszName, uint32_t cbName)
    485 {
    486     LogFlowFunc(("cbName=%d\n", cbName));
    487     int rc = VINF_SUCCESS;
    488     if (RT_SUCCESS(rc) && (cbName < 2))
    489         rc = VERR_INVALID_PARAMETER;
    490     for (unsigned i = 0; RT_SUCCESS(rc) && i < cbName; ++i)
    491         if (pszName[i] == '*' || pszName[i] == '?' || pszName[i] == '|')
    492             rc = VERR_INVALID_PARAMETER;
    493     LogFlowFunc(("returning %Rrc\n", rc));
    494     return rc;
    495 }
    496 
    497 
    498 /**
    499  * Check a string fits our criteria for the value of a guest property.
    500  *
    501  * @returns IPRT status code
    502  * @param   pszValue  the string to check, must be valid Utf8
    503  * @param   cbValue   the length in bytes of @a pszValue, including the
    504  *                    terminator
    505  * @thread  HGCM
    506  */
    507 int Service::validateValue(const char *pszValue, uint32_t cbValue)
    508 {
    509     LogFlowFunc(("cbValue=%d\n", cbValue)); RT_NOREF1(pszValue);
    510 
    511     int rc = VINF_SUCCESS;
    512     if (RT_SUCCESS(rc) && cbValue == 0)
    513         rc = VERR_INVALID_PARAMETER;
    514     if (RT_SUCCESS(rc))
    515         LogFlow(("    pszValue=%s\n", cbValue > 0 ? pszValue : NULL));
    516     LogFlowFunc(("returning %Rrc\n", rc));
    517     return rc;
    518471}
    519472
     
    644597        rc = VERR_INVALID_PARAMETER;
    645598    else
    646         rc = validateName(pcszName, cbName);
     599        rc = GuestPropValidateName(pcszName, cbName);
    647600    if (RT_FAILURE(rc))
    648601    {
     
    736689     */
    737690    if (RT_SUCCESS(rc))
    738         rc = validateName(pcszName, cchName);
     691        rc = GuestPropValidateName(pcszName, cchName);
    739692    if (RT_SUCCESS(rc))
    740         rc = validateValue(pcszValue, cchValue);
     693        rc = GuestPropValidateValue(pcszValue, cchValue);
    741694    if ((3 == cParms) && RT_SUCCESS(rc))
    742695        rc = RTStrValidateEncodingEx(pcszFlags, cchFlags,
     
    869822        && RT_SUCCESS(HGCMSvcGetCStr(&paParms[0], &pcszName, &cbName))  /* name */
    870823       )
    871         rc = validateName(pcszName, cbName);
     824        rc = GuestPropValidateName(pcszName, cbName);
    872825    else
    873826        rc = VERR_INVALID_PARAMETER;
     
    13421295        {
    13431296            /* Send out a host notification */
    1344             rc = notifyHost(pszProperty, "", nsTimestamp, "");
     1297            rc = notifyHost(pszProperty, NULL, nsTimestamp, "");
    13451298        }
    13461299    }
     
    13881341        *pu8++ = 0;
    13891342
    1390         pHostCallbackData->pcszValue    = (const char *)pu8;
     1343        /* NULL value means property was deleted. */
     1344        pHostCallbackData->pcszValue    = pszValue ? (const char *)pu8 : NULL;
    13911345        memcpy(pu8, pszValue, cbValue);
    13921346        pu8 += cbValue;
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r93835 r93891  
    53205320        </desc>
    53215321      </param>
     5322      <param name="fWasDeleted" type="boolean" dir="in">
     5323        <desc>
     5324          The flag which indicates if property was deleted.
     5325        </desc>
     5326      </param>
    53225327    </method>
    53235328
  • trunk/src/VBox/Main/include/MachineImpl.h

    r93548 r93891  
    12341234                              const com::Utf8Str &aValue,
    12351235                              LONG64 aTimestamp,
    1236                               const com::Utf8Str &aFlags);
     1236                              const com::Utf8Str &aFlags,
     1237                              BOOL fWasDeleted);
    12371238    HRESULT lockMedia();
    12381239    HRESULT unlockMedia();
     
    13901391                              const com::Utf8Str &aValue,
    13911392                              LONG64 aTimestamp,
    1392                               const com::Utf8Str &aFlags);
     1393                              const com::Utf8Str &aFlags,
     1394                              BOOL fWasDeleted);
    13931395    HRESULT lockMedia();
    13941396    HRESULT unlockMedia();
  • trunk/src/VBox/Main/src-client/ConsoleImpl.cpp

    r93859 r93891  
    18491849                                                        value.raw(),
    18501850                                                        pCBData->u64Timestamp,
    1851                                                         flags.raw());
     1851                                                        flags.raw(),
     1852                                                        !pCBData->pcszValue);
    18521853    if (SUCCEEDED(hrc))
    18531854    {
  • trunk/src/VBox/Main/src-server/MachineImpl.cpp

    r93639 r93891  
    56555655    ReturnComNotImplemented();
    56565656#else // VBOX_WITH_GUEST_PROPS
     5657    AssertReturn(RT_SUCCESS(GuestPropValidateName(aProperty.c_str(), (uint32_t)aProperty.length() + 1 /* '\0' */)), E_INVALIDARG);
     5658    AssertReturn(RT_SUCCESS(GuestPropValidateValue(aValue.c_str(), (uint32_t)aValue.length() + 1  /* '\0' */)), E_INVALIDARG);
     5659
    56575660    HRESULT rc = i_setGuestPropertyToVM(aProperty, aValue, aFlags, /* fDelete = */ false);
    56585661    if (rc == E_ACCESSDENIED)
     
    57375740        GuestPropWriteFlags(it->second.mFlags, szFlags);
    57385741        aFlags[i] = Utf8Str(szFlags);
     5742
     5743        AssertReturn(RT_SUCCESS(GuestPropValidateName(aNames[i].c_str(), (uint32_t)aNames[i].length() + 1 /* '\0' */)), E_INVALIDARG);
     5744        AssertReturn(RT_SUCCESS(GuestPropValidateValue(aValues[i].c_str(), (uint32_t)aValues[i].length() + 1 /* '\0' */)), E_INVALIDARG);
    57395745    }
    57405746
     
    1357213578        else
    1357313579            aFlags[i] = "";
     13580
     13581        AssertReturn(RT_SUCCESS(GuestPropValidateName(aNames[i].c_str(), (uint32_t)aNames[i].length() + 1 /* '\0' */)), E_INVALIDARG);
     13582        AssertReturn(RT_SUCCESS(GuestPropValidateValue(aValues[i].c_str(), (uint32_t)aValues[i].length() + 1 /* '\0' */)), E_INVALIDARG);
    1357413583    }
    1357513584    return S_OK;
     
    1358213591                                          const com::Utf8Str &aValue,
    1358313592                                          LONG64 aTimestamp,
    13584                                           const com::Utf8Str &aFlags)
     13593                                          const com::Utf8Str &aFlags,
     13594                                          BOOL fWasDeleted)
    1358513595{
    1358613596    LogFlowThisFunc(("\n"));
     
    1361113621        mHWData.backup();
    1361213622
    13613         bool fDelete = !aValue.length();
    1361413623        HWData::GuestPropertyMap::iterator it = mHWData->mGuestProperties.find(aName);
    1361513624        if (it != mHWData->mGuestProperties.end())
    1361613625        {
    13617             if (!fDelete)
     13626            if (!fWasDeleted)
    1361813627            {
    1361913628                it->second.strValue   = aValue;
     
    1362613635            mData->mGuestPropertiesModified = TRUE;
    1362713636        }
    13628         else if (!fDelete)
     13637        else if (!fWasDeleted)
    1362913638        {
    1363013639            HWData::GuestProperty prop;
     
    1504615055                                   const com::Utf8Str &aValue,
    1504715056                                   LONG64 aTimestamp,
    15048                                    const com::Utf8Str &aFlags)
     15057                                   const com::Utf8Str &aFlags,
     15058                                   BOOL fWasDeleted)
    1504915059{
    1505015060    NOREF(aName);
     
    1505215062    NOREF(aTimestamp);
    1505315063    NOREF(aFlags);
     15064    NOREF(fWasDeleted);
    1505415065    ReturnComNotImplemented();
    1505515066}
Note: See TracChangeset for help on using the changeset viewer.

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