VirtualBox

Changeset 61978 in vbox for trunk


Ignore:
Timestamp:
Jul 1, 2016 1:42:28 PM (8 years ago)
Author:
vboxsync
Message:

Storage/iSCSI: Fix a possible crash during VM resume when connectin to the target fails in iscsiSetOpenFlags (readonly -> read/write transition). Failing the connection attempt here leaves the image data in an inconsistent state leading to memory corruption later on if iscsiWrite/iscsiRead is called. Don't do any communication with the target in iscsiSetOpenFlags but use the remembered data from the first login to decide whether the transition is allowed. Introduce a new flag to indicate whether a reconnect attempt should be made from the I/O worker thread before processing new requests to try reconnecting after a VM resume which was suspended due to an unresponsive target

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Storage/ISCSI.cpp

    r61037 r61978  
    573573    /** Flag whether to dump malformed packets in the release log. */
    574574    bool                fDumpMalformedPackets;
     575    /** Flag whtether the target is readonly. */
     576    bool                fTargetReadOnly;
     577    /** Flag whether to retry the connection before processing new requests. */
     578    bool                fTryReconnect;
    575579
    576580    /** Head of request queue */
     
    34363440                    case ISCSICMDTYPE_REQ:
    34373441                    {
     3442                        if (   !iscsiIsClientConnected(pImage)
     3443                            && pImage->fTryReconnect)
     3444                        {
     3445                            pImage->fTryReconnect = false;
     3446                            iscsiReattach(pImage);
     3447                        }
     3448   
    34383449                        /* If there is no connection complete the command with an error. */
    34393450                        if (RT_LIKELY(iscsiIsClientConnected(pImage)))
     
    42754286    if (RT_SUCCESS(rc))
    42764287    {
    4277         if (!(uOpenFlags & VD_OPEN_FLAGS_READONLY) && data4[2] & 0x80)
     4288        pImage->fTargetReadOnly = !!(data4[2] & 0x80);
     4289        if (!(uOpenFlags & VD_OPEN_FLAGS_READONLY) && pImage->fTargetReadOnly)
    42784290        {
    42794291            rc = VERR_VD_IMAGE_READ_ONLY;
     
    51635175static DECLCALLBACK(int) iscsiSetOpenFlags(void *pBackendData, unsigned uOpenFlags)
    51645176{
    5165     LogFlowFunc(("pBackendData=%#p\n uOpenFlags=%#x", pBackendData, uOpenFlags));
     5177    LogFlowFunc(("pBackendData=%#p uOpenFlags=%#x\n", pBackendData, uOpenFlags));
    51665178    PISCSIIMAGE pImage = (PISCSIIMAGE)pBackendData;
    5167     int rc;
     5179    int rc = VINF_SUCCESS;
    51685180
    51695181    /* Image must be opened and the new flags must be valid. */
    5170     if (!pImage || (uOpenFlags & ~(  VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO
    5171                                    | VD_OPEN_FLAGS_ASYNC_IO | VD_OPEN_FLAGS_SHAREABLE
    5172                                    | VD_OPEN_FLAGS_SEQUENTIAL | VD_OPEN_FLAGS_SKIP_CONSISTENCY_CHECKS)))
    5173     {
    5174         rc = VERR_INVALID_PARAMETER;
    5175         goto out;
    5176     }
    5177 
    5178     /* Implement this operation via reopening the image if we actually need
    5179      * to do something. A read/write -> readonly transition doesn't need a
    5180      * reopen. In the other direction we don't have the necessary information
    5181      * as the "disk is readonly" flag is thrown away. Can be optimized too,
    5182      * but it's not worth the effort at the moment. */
     5182    AssertReturn(pImage && !(uOpenFlags & ~(  VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO
     5183                                            | VD_OPEN_FLAGS_ASYNC_IO | VD_OPEN_FLAGS_SHAREABLE
     5184                                            | VD_OPEN_FLAGS_SEQUENTIAL | VD_OPEN_FLAGS_SKIP_CONSISTENCY_CHECKS)),
     5185                 VERR_INVALID_PARAMETER);
     5186
     5187    /*
     5188     * A read/write -> readonly transition is always possible,
     5189     * for the reverse direction check that the target didn't present itself
     5190     * as readonly during the first attach.
     5191     */
    51835192    if (   !(uOpenFlags & VD_OPEN_FLAGS_READONLY)
    5184         && (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
    5185     {
    5186         iscsiFreeImage(pImage, false);
    5187         rc = iscsiOpenImage(pImage, uOpenFlags);
    5188     }
     5193        && (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
     5194        && pImage->fTargetReadOnly)
     5195        rc = VERR_VD_IMAGE_READ_ONLY;
    51895196    else
    51905197    {
    51915198        pImage->uOpenFlags = uOpenFlags;
    5192         rc = VINF_SUCCESS;
    5193     }
    5194 out:
     5199        pImage->fTryReconnect = true;
     5200    }
     5201
    51955202    LogFlowFunc(("returns %Rrc\n", rc));
    51965203    return 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