VirtualBox

Changeset 92083 in vbox for trunk/src


Ignore:
Timestamp:
Oct 26, 2021 2:08:57 PM (3 years ago)
Author:
vboxsync
Message:

IPRT/VFS: 'VBoxManage import VM.ova' can fail due to reading some of the
data twice. bugref:9730

Attempting to import a VM may fail on hosts such as Solaris which use
the Runtime/posix/r3 implementation of RTFileReadAt() or RTFileWriteAt().
These routines on POSIX platforms leverage pread(2) and pwrite(2)
respectively which don't update the file-position indicator which means
callers need to take this into account. The appliance import code could
run into this when rtVfsStdFile_Read() is called with a non-negative
offset.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/vfs/vfsstdfile.cpp

    r82968 r92083  
    143143            rc = RTFileRead(  pThis->hFile,      pSgBuf->paSegs[0].pvSeg, pSgBuf->paSegs[0].cbSeg, pcbRead);
    144144        else
     145        {
    145146            rc = RTFileReadAt(pThis->hFile, off, pSgBuf->paSegs[0].pvSeg, pSgBuf->paSegs[0].cbSeg, pcbRead);
     147            if (RT_SUCCESS(rc)) /* RTFileReadAt() doesn't increment the file-position indicator on some platforms */
     148                rc = RTFileSeek(pThis->hFile, off + (pcbRead ? *pcbRead : pSgBuf->paSegs[0].cbSeg), RTFILE_SEEK_BEGIN, NULL);
     149        }
    146150        if (rc == VINF_SUCCESS && pcbRead)
    147151            rc = rtVfsStdFile_ReadFixRC(pThis, off, pSgBuf->paSegs[0].cbSeg, *pcbRead);
     
    163167                rc = RTFileRead(  pThis->hFile,      pvSeg, cbSeg, pcbRead ? &cbReadSeg : NULL);
    164168            else
     169            {
    165170                rc = RTFileReadAt(pThis->hFile, off, pvSeg, cbSeg, pcbRead ? &cbReadSeg : NULL);
     171                if (RT_SUCCESS(rc)) /* RTFileReadAt() doesn't increment the file-position indicator on some platforms */
     172                    rc = RTFileSeek(pThis->hFile, off + cbReadSeg, RTFILE_SEEK_BEGIN, NULL);
     173            }
    166174            if (RT_FAILURE(rc))
    167175                break;
     
    199207            rc = RTFileWrite(pThis->hFile, pSgBuf->paSegs[0].pvSeg, pSgBuf->paSegs[0].cbSeg, pcbWritten);
    200208        else
     209        {
    201210            rc = RTFileWriteAt(pThis->hFile, off, pSgBuf->paSegs[0].pvSeg, pSgBuf->paSegs[0].cbSeg, pcbWritten);
     211            if (RT_SUCCESS(rc)) /* RTFileWriteAt() doesn't increment the file-position indicator on some platforms */
     212                rc = RTFileSeek(pThis->hFile, off + (pcbWritten ? *pcbWritten : pSgBuf->paSegs[0].cbSeg), RTFILE_SEEK_BEGIN,
     213                                NULL);
     214        }
    202215    }
    203216    else
     
    219232            {
    220233                rc = RTFileWriteAt(pThis->hFile, off, pvSeg, cbSeg, pcbWrittenSeg);
    221                 off += cbSeg;
     234                if (RT_SUCCESS(rc))
     235                {
     236                    off += pcbWrittenSeg ? *pcbWrittenSeg : cbSeg;
     237                    /* RTFileWriteAt() doesn't increment the file-position indicator on some platforms */
     238                    rc = RTFileSeek(pThis->hFile, off, RTFILE_SEEK_BEGIN, NULL);
     239                }
    222240            }
    223241            if (RT_FAILURE(rc))
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