VirtualBox

Changeset 49923 in vbox for trunk/src/VBox/Additions


Ignore:
Timestamp:
Dec 16, 2013 9:36:45 AM (11 years ago)
Author:
vboxsync
Message:

DnD/VbglR3: Sanitize file/directory paths coming from the host, fixed a few memory leaks, added some more todos.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDragAndDrop.cpp

    r49891 r49923  
    5151 */
    5252
     53int vbglR3DnDPathSanitize(char *pszPath, size_t cbPath);
     54
    5355/******************************************************************************
    5456 *    Private internal functions                                              *
     
    9092    if (!RTTimeSpecToString(RTTimeNow(&time), pszTime, sizeof(pszTime)))
    9193        return VERR_BUFFER_OVERFLOW;
    92 #ifdef RT_OS_WINDOWS
    93     /* Filter out characters not allowed on Windows platforms, put in by
    94        RTTimeSpecToString(). */
    95     /** @todo Use something like RTPathSanitize() when available. Later. */
    96     RTUNICP aCpSet[] =
    97         { ' ', ' ', '(', ')', '-', '.', '0', '9', 'A', 'Z', 'a', 'z', '_', '_',
    98           0xa0, 0xd7af, '\0' };
    99     RTStrPurgeComplementSet(pszTime, aCpSet, '_' /* Replacement */);
    100 #endif
     94    rc = vbglR3DnDPathSanitize(pszTime, sizeof(pszTime));
     95    if (RT_FAILURE(rc))
     96        return rc;
    10197
    10298    rc = RTPathAppend(pszDropDir, cbSize, pszTime);
     
    319315                                         size_t    *pcbDataRecv)
    320316{
     317    AssertPtrReturn(ppvData, VERR_INVALID_POINTER);
     318    AssertPtrReturn(cbData, VERR_INVALID_PARAMETER);
     319    AssertPtrReturn(pcbDataRecv, VERR_INVALID_POINTER);
     320
    321321    /* Make a string list out of the uri data. */
    322322    RTCList<RTCString> uriList = RTCString(static_cast<char*>(*ppvData), *pcbDataRecv - 1).split("\r\n");
     
    324324        return VINF_SUCCESS;
    325325
    326     uint32_t cbTmpData = _1M * 10;
     326    uint32_t cbTmpData = _1M * 10; /** @todo r=andy 10MB, uh, really?? */
    327327    void *pvTmpData = RTMemAlloc(cbTmpData);
    328328    if (!pvTmpData)
     
    346346        /* Query the path component of a file URI. If this hasn't a
    347347         * file scheme, null is returned. */
    348         if (char *pszFilePath = RTUriFilePath(strUri.c_str(), URI_FILE_FORMAT_AUTO))
    349         {
     348        char *pszFilePath = RTUriFilePath(strUri.c_str(), URI_FILE_FORMAT_AUTO);
     349        if (pszFilePath)
     350        {
     351            rc = vbglR3DnDPathSanitize(pszFilePath, strlen(pszFilePath));
     352            if (RT_FAILURE(rc))
     353                break;
     354
     355            /** @todo Use RTPathJoin? */
    350356            RTCString strFullPath = RTCString().printf("%s%c%s", pszDropDir, RTPATH_SLASH, pszFilePath);
    351357            char *pszNewUri = RTUriFileCreate(strFullPath.c_str());
     
    360366    }
    361367
    362     /* Cleanup the old data and write the new data back to the event. */
    363     RTMemFree(*ppvData);
    364     RTCString newData = RTCString::join(guestUriList, "\r\n") + "\r\n";
    365     *ppvData = RTStrDupN(newData.c_str(), newData.length());
    366     *pcbDataRecv = newData.length() + 1;
     368    if (RT_SUCCESS(rc))
     369    {
     370        /* Cleanup the old data and write the new data back to the event. */
     371        RTMemFree(*ppvData);
     372        RTCString newData = RTCString::join(guestUriList, "\r\n") + "\r\n";
     373
     374        *ppvData = RTStrDupN(newData.c_str(), newData.length());
     375        *pcbDataRecv = newData.length() + 1;
     376    }
    367377
    368378    /* Lists for holding created files & directories in the case of a
     
    372382    char pszPathname[RTPATH_MAX];
    373383    uint32_t cbPathname = 0;
    374     bool fLoop = true;
    375     do
     384    bool fLoop = RT_SUCCESS(rc); /* No error occurred yet? */
     385    while (fLoop)
    376386    {
    377387        uint32_t uNextMsg;
     
    380390        if (RT_SUCCESS(rc))
    381391        {
    382             switch(uNextMsg)
     392            switch (uNextMsg)
    383393            {
    384394                case DragAndDropSvc::HOST_DND_HG_SND_DIR:
    385                 {
    386                     uint32_t fMode = 0;
    387                     rc = vbglR3DnDHGProcessSendDirMessage(uClientId,
    388                                                           pszPathname,
    389                                                           sizeof(pszPathname),
    390                                                           &cbPathname,
    391                                                           &fMode);
    392                     if (RT_SUCCESS(rc))
    393395                    {
    394                         char *pszNewDir = RTPathJoinA(pszDropDir, pszPathname);
    395                         rc = RTDirCreate(pszNewDir, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRWXU, 0);
    396                         if (!guestDirList.contains(pszNewDir))
    397                             guestDirList.append(pszNewDir);
    398                     }
    399                     break;
    400                 }
    401                 case DragAndDropSvc::HOST_DND_HG_SND_FILE:
    402                 {
    403                     uint32_t cbDataRecv;
    404                     uint32_t fMode = 0;
    405                     rc = vbglR3DnDHGProcessSendFileMessage(uClientId,
    406                                                            pszPathname,
    407                                                            sizeof(pszPathname),
    408                                                            &cbPathname,
    409                                                            pvTmpData,
    410                                                            cbTmpData,
    411                                                            &cbDataRecv,
    412                                                            &fMode);
    413                     if (RT_SUCCESS(rc))
    414                     {
    415                         char *pszNewFile = RTPathJoinA(pszDropDir, pszPathname);
    416                         RTFILE hFile;
    417                         /** @todo r=andy Keep the file open and locked during the actual file transfer. Otherwise this will
    418                          *               create all sorts of funny races because we don't know if the guest has
    419                          *               modified the file in between the file data send calls. */
    420                         rc = RTFileOpen(&hFile, pszNewFile, RTFILE_O_WRITE | RTFILE_O_APPEND | RTFILE_O_DENY_ALL | RTFILE_O_OPEN_CREATE);
     396                        uint32_t fMode = 0;
     397                        rc = vbglR3DnDHGProcessSendDirMessage(uClientId,
     398                                                              pszPathname,
     399                                                              sizeof(pszPathname),
     400                                                              &cbPathname,
     401                                                              &fMode);
     402                        if (RT_SUCCESS(rc))
     403                            rc = vbglR3DnDPathSanitize(pszPathname, sizeof(pszPathname));
    421404                        if (RT_SUCCESS(rc))
    422405                        {
    423                             rc = RTFileSeek(hFile, 0, RTFILE_SEEK_END, NULL);
    424                             if (RT_SUCCESS(rc))
     406                            char *pszNewDir = RTPathJoinA(pszDropDir, pszPathname);
     407                            if (pszNewDir)
    425408                            {
    426                                 rc = RTFileWrite(hFile, pvTmpData, cbDataRecv, 0);
    427                                 /* Valid UNIX mode? */
    428                                 if (   RT_SUCCESS(rc)
    429                                     && (fMode & RTFS_UNIX_MASK))
    430                                     rc = RTFileSetMode(hFile, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRUSR | RTFS_UNIX_IWUSR);
     409                                rc = RTDirCreate(pszNewDir, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRWXU, 0);
     410                                if (!guestDirList.contains(pszNewDir))
     411                                    guestDirList.append(pszNewDir);
     412
     413                                RTStrFree(pszNewDir);
    431414                            }
    432                             RTFileClose(hFile);
    433                             if (!guestFileList.contains(pszNewFile))
    434                                 guestFileList.append(pszNewFile);
     415                            else
     416                                rc = VERR_NO_MEMORY;
    435417                        }
     418                        break;
    436419                    }
    437                     break;
    438                 }
     420                case DragAndDropSvc::HOST_DND_HG_SND_FILE:
     421                    {
     422                        uint32_t cbDataRecv;
     423                        uint32_t fMode = 0;
     424                        rc = vbglR3DnDHGProcessSendFileMessage(uClientId,
     425                                                               pszPathname,
     426                                                               sizeof(pszPathname),
     427                                                               &cbPathname,
     428                                                               pvTmpData,
     429                                                               cbTmpData,
     430                                                               &cbDataRecv,
     431                                                               &fMode);
     432                        if (RT_SUCCESS(rc))
     433                            rc = vbglR3DnDPathSanitize(pszPathname, sizeof(pszPathname));
     434                        if (RT_SUCCESS(rc))
     435                        {
     436                            char *pszNewFile = RTPathJoinA(pszDropDir, pszPathname);
     437                            if (pszNewFile)
     438                            {
     439                                RTFILE hFile;
     440                                /** @todo r=andy Keep the file open and locked during the actual file transfer. Otherwise this will
     441                                 *               create all sorts of funny races because we don't know if the guest has
     442                                 *               modified the file in between the file data send calls. */
     443                                rc = RTFileOpen(&hFile, pszNewFile, RTFILE_O_WRITE | RTFILE_O_APPEND | RTFILE_O_DENY_ALL | RTFILE_O_OPEN_CREATE);
     444                                if (RT_SUCCESS(rc))
     445                                {
     446                                    rc = RTFileSeek(hFile, 0, RTFILE_SEEK_END, NULL);
     447                                    if (RT_SUCCESS(rc))
     448                                    {
     449                                        rc = RTFileWrite(hFile, pvTmpData, cbDataRecv, 0);
     450                                        /* Valid UNIX mode? */
     451                                        if (RT_SUCCESS(rc)
     452                                            && (fMode & RTFS_UNIX_MASK)) rc = RTFileSetMode(hFile, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRUSR | RTFS_UNIX_IWUSR);
     453                                    }
     454                                    RTFileClose(hFile);
     455                                    if (!guestFileList.contains(pszNewFile))
     456                                        guestFileList.append(pszNewFile);
     457                                }
     458
     459                                RTStrFree(pszNewFile);
     460                            }
     461                            else
     462                                rc = VERR_NO_MEMORY;
     463                        }
     464                        break;
     465                    }
    439466                case DragAndDropSvc::HOST_DND_HG_EVT_CANCEL:
    440                 {
    441                     rc = vbglR3DnDHGProcessCancelMessage(uClientId);
    442                     if (RT_SUCCESS(rc))
    443                         rc = VERR_CANCELLED;
    444                     /* Break out of the loop. */
    445                 }
     467                    {
     468                        rc = vbglR3DnDHGProcessCancelMessage(uClientId);
     469                        if (RT_SUCCESS(rc)) rc = VERR_CANCELLED;
     470                        /* Break out of the loop. */
     471                    }
    446472                default:
    447473                    fLoop = false;
     
    451477        else
    452478        {
    453             if (rc == VERR_NO_DATA)
    454                 rc = VINF_SUCCESS;
     479            if (rc == VERR_NO_DATA) rc = VINF_SUCCESS;
    455480            break;
    456481        }
    457 
    458     } while (fLoop);
     482    } /* while */
    459483
    460484    RTMemFree(pvTmpData);
     
    507531    {
    508532        rc = Msg.hdr.result;
    509         if (   RT_SUCCESS(rc)
     533        if (RT_SUCCESS(rc)
    510534            || rc == VERR_BUFFER_OVERFLOW)
    511535        {
     
    715739    }
    716740
     741    return rc;
     742}
     743
     744int vbglR3DnDPathSanitize(char *pszPath, size_t cbPath)
     745{
     746    int rc = VINF_SUCCESS;
     747#ifdef RT_OS_WINDOWS
     748    /* Filter out characters not allowed on Windows platforms, put in by
     749       RTTimeSpecToString(). */
     750    /** @todo Use something like RTPathSanitize() when available. Later. */
     751    RTUNICP aCpSet[] =
     752        { ' ', ' ', '(', ')', '-', '.', '0', '9', 'A', 'Z', 'a', 'z', '_', '_',
     753          0xa0, 0xd7af, '\0' };
     754    ssize_t cReplaced = RTStrPurgeComplementSet(pszPath, aCpSet, '_' /* Replacement */);
     755    if (cReplaced < 0)
     756        rc = VERR_INVALID_UTF8_ENCODING;
     757#endif
    717758    return rc;
    718759}
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