VirtualBox

Changeset 33415 in vbox for trunk


Ignore:
Timestamp:
Oct 25, 2010 12:05:16 PM (14 years ago)
Author:
vboxsync
Message:

GuestCopy/VBoxService: Bugfix for writing to closed pipe buffers.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp

    r33297 r33415  
    784784    AssertPtrReturn(pcbWritten, VERR_INVALID_PARAMETER);
    785785
    786     int rc = RTCritSectEnter(&pBuf->CritSect);
    787     if (RT_SUCCESS(rc))
    788     {
    789         /* Rewind the buffer if it's empty. */
    790         size_t     cbInBuf   = pBuf->cbSize - pBuf->cbOffset;
    791         bool const fAddToSet = cbInBuf == 0;
    792         if (fAddToSet)
    793             pBuf->cbSize = pBuf->cbOffset = 0;
    794 
    795         /* Try and see if we can simply append the data. */
    796         if (cbData + pBuf->cbSize <= pBuf->cbAllocated)
    797         {
    798             memcpy(&pBuf->pbData[pBuf->cbSize], pbData, cbData);
    799             pBuf->cbSize += cbData;
    800         }
    801         else
    802         {
    803             /* Move any buffered data to the front. */
    804             cbInBuf = pBuf->cbSize - pBuf->cbOffset;
    805             if (cbInBuf == 0)
     786    int rc;
     787    if (pBuf->fAlive)
     788    {
     789        rc = RTCritSectEnter(&pBuf->CritSect);
     790        if (RT_SUCCESS(rc))
     791        {
     792            /* Rewind the buffer if it's empty. */
     793            size_t     cbInBuf   = pBuf->cbSize - pBuf->cbOffset;
     794            bool const fAddToSet = cbInBuf == 0;
     795            if (fAddToSet)
    806796                pBuf->cbSize = pBuf->cbOffset = 0;
    807             else if (pBuf->cbOffset) /* Do we have something to move? */
    808             {
    809                 memmove(pBuf->pbData, &pBuf->pbData[pBuf->cbOffset], cbInBuf);
    810                 pBuf->cbSize = cbInBuf;
    811                 pBuf->cbOffset = 0;
    812             }
    813 
    814             /* Do we need to grow the buffer? */
    815             if (cbData + pBuf->cbSize > pBuf->cbAllocated)
    816             {
    817                 size_t cbAlloc = pBuf->cbSize + cbData;
    818                 cbAlloc = RT_ALIGN_Z(cbAlloc, _64K);
    819                 void *pvNew = RTMemRealloc(pBuf->pbData, cbAlloc);
    820                 if (pvNew)
    821                 {
    822                     pBuf->pbData = (uint8_t *)pvNew;
    823                     pBuf->cbAllocated = cbAlloc;
    824                 }
    825                 else
    826                     rc = VERR_NO_MEMORY;
    827             }
    828 
    829             /* Finally, copy the data. */
     797
     798            /* Try and see if we can simply append the data. */
     799            if (cbData + pBuf->cbSize <= pBuf->cbAllocated)
     800            {
     801                memcpy(&pBuf->pbData[pBuf->cbSize], pbData, cbData);
     802                pBuf->cbSize += cbData;
     803            }
     804            else
     805            {
     806                /* Move any buffered data to the front. */
     807                cbInBuf = pBuf->cbSize - pBuf->cbOffset;
     808                if (cbInBuf == 0)
     809                    pBuf->cbSize = pBuf->cbOffset = 0;
     810                else if (pBuf->cbOffset) /* Do we have something to move? */
     811                {
     812                    memmove(pBuf->pbData, &pBuf->pbData[pBuf->cbOffset], cbInBuf);
     813                    pBuf->cbSize = cbInBuf;
     814                    pBuf->cbOffset = 0;
     815                }
     816
     817                /* Do we need to grow the buffer? */
     818                if (cbData + pBuf->cbSize > pBuf->cbAllocated)
     819                {
     820                    size_t cbAlloc = pBuf->cbSize + cbData;
     821                    cbAlloc = RT_ALIGN_Z(cbAlloc, _64K);
     822                    void *pvNew = RTMemRealloc(pBuf->pbData, cbAlloc);
     823                    if (pvNew)
     824                    {
     825                        pBuf->pbData = (uint8_t *)pvNew;
     826                        pBuf->cbAllocated = cbAlloc;
     827                    }
     828                    else
     829                        rc = VERR_NO_MEMORY;
     830                }
     831
     832                /* Finally, copy the data. */
     833                if (RT_SUCCESS(rc))
     834                {
     835                    if (cbData + pBuf->cbSize <= pBuf->cbAllocated)
     836                    {
     837                        memcpy(&pBuf->pbData[pBuf->cbSize], pbData, cbData);
     838                        pBuf->cbSize += cbData;
     839                    }
     840                    else
     841                        rc = VERR_BUFFER_OVERFLOW;
     842                }
     843            }
     844
    830845            if (RT_SUCCESS(rc))
    831846            {
    832                 if (cbData + pBuf->cbSize <= pBuf->cbAllocated)
    833                 {
    834                     memcpy(&pBuf->pbData[pBuf->cbSize], pbData, cbData);
    835                     pBuf->cbSize += cbData;
    836                 }
    837                 else
    838                     rc = VERR_BUFFER_OVERFLOW;
    839             }
    840         }
    841 
    842         if (RT_SUCCESS(rc))
    843         {
    844             /* Report back written bytes. */
    845             *pcbWritten = cbData;
    846 
    847             /*
    848              * Was this the final read/write to do on this buffer? The close it
    849              * next time we have the chance to.
    850              */
    851             if (fPendingClose)
    852                 pBuf->fPendingClose = fPendingClose;
    853 
    854             /*
    855              * Wake up the thread servicing the process so it can feed it
    856              * (if we have a notification helper pipe).
    857              */
    858             if (pBuf->fNeedNotification)
    859             {
    860                 size_t cbWritten;
    861                 int rc2 = RTPipeWrite(pBuf->hNotificationPipeW, "i", 1, &cbWritten);
    862 
    863                 /* Disable notification until it is set again on successful write. */
    864                 pBuf->fNeedNotification = !RT_SUCCESS(rc2);
    865             }
    866         }
    867         int rc2 = RTCritSectLeave(&pBuf->CritSect);
    868         if (RT_SUCCESS(rc))
    869             rc = rc2;
    870     }
     847                /* Report back written bytes. */
     848                *pcbWritten = cbData;
     849
     850                /*
     851                 * Was this the final read/write to do on this buffer? The close it
     852                 * next time we have the chance to.
     853                 */
     854                if (fPendingClose)
     855                    pBuf->fPendingClose = fPendingClose;
     856
     857                /*
     858                 * Wake up the thread servicing the process so it can feed it
     859                 * (if we have a notification helper pipe).
     860                 */
     861                if (pBuf->fNeedNotification)
     862                {
     863                    size_t cbWritten;
     864                    int rc2 = RTPipeWrite(pBuf->hNotificationPipeW, "i", 1, &cbWritten);
     865
     866                    /* Disable notification until it is set again on successful write. */
     867                    pBuf->fNeedNotification = !RT_SUCCESS(rc2);
     868                }
     869            }
     870            int rc2 = RTCritSectLeave(&pBuf->CritSect);
     871            if (RT_SUCCESS(rc))
     872                rc = rc2;
     873        }
     874    }
     875    else
     876        rc = VERR_BAD_PIPE;
    871877    return rc;
    872878}
     
    15701576#ifdef DEBUG
    15711577            VBoxServiceVerbose(4, "ControlExec: Written to StdIn buffer (PID %u): rc=%Rrc, uFlags=0x%x, cbAlloc=%u, cbSize=%u, cbOffset=%u\n",
    1572                                uPID, rc, pData->stdIn.cbAllocated, pData->stdIn.cbSize,
    1573                                pData->stdIn.cbOffset);
     1578                               uPID, rc, uFlags,
     1579                               pData->stdIn.cbAllocated, pData->stdIn.cbSize, pData->stdIn.cbOffset);
    15741580#endif
    15751581            uint32_t uStatus = INPUT_STS_UNDEFINED;
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