VirtualBox

Ignore:
Timestamp:
May 2, 2022 7:47:56 PM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
151178
Message:

Main/Medium: Fix the refcount updating behavior of Medium::uninit. It must not increase the refcount of "this" since this could cause double freeing since the uninit call might have been triggered by the refcount reaching 0. bugref:7717

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-server/MediumImpl.cpp

    r94600 r94787  
    13891389    llParentsTodo.push_back(NULL);
    13901390
    1391     while (llSettingsTodo.size() > 0)
     1391    while (!llSettingsTodo.empty())
    13921392    {
    13931393        const settings::Medium *current = llSettingsTodo.front();
     
    15801580    AutoWriteLock treeLock(pVirtualBox->i_getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
    15811581
    1582     MediaList llMediaTodo;
     1582    /* Must use a list without refcounting help since "this" might already have
     1583     * reached 0, and then the refcount must not be increased again since it
     1584     * would otherwise trigger a double free. For all other list entries this
     1585     * needs manual refcount updating, to make sure the refcount for children
     1586     * does not drop to 0 too early. */
     1587    std::list<Medium *> llMediaTodo;
    15831588    llMediaTodo.push_back(this);
    15841589
    15851590    while (!llMediaTodo.empty())
    15861591    {
    1587         /* This also guarantees that the refcount doesn't actually drop to 0
    1588          * again while the uninit is already ongoing. */
    1589         ComObjPtr<Medium> pMedium = llMediaTodo.front();
     1592        Medium *pMedium = llMediaTodo.front();
    15901593        llMediaTodo.pop_front();
    15911594
     
    15931596        AutoUninitSpan autoUninitSpan(pMedium);
    15941597        if (autoUninitSpan.uninitDone())
     1598        {
     1599            if (pMedium != this)
     1600                pMedium->Release();
    15951601            continue;
     1602        }
    15961603
    15971604        Assert(!pMedium->isWriteLockOnCurrentThread());
     
    16041611        pMedium->m->formatObj.setNull();
    16051612
    1606         if (m->state == MediumState_Deleting)
     1613        if (pMedium->m->state == MediumState_Deleting)
    16071614        {
    16081615            /* This medium has been already deleted (directly or as part of a
    16091616             * merge).  Reparenting has already been done. */
    1610             Assert(m->pParent.isNull());
    1611             Assert(m->llChildren.empty());
     1617            Assert(pMedium->m->pParent.isNull());
     1618            Assert(pMedium->m->llChildren.empty());
     1619            if (pMedium != this)
     1620                pMedium->Release();
    16121621            continue;
    16131622        }
     
    16261635            Medium *pChild = *it;
    16271636            pChild->m->pParent.setNull();
     1637            pChild->AddRef();
    16281638            llMediaTodo.push_back(pChild);
    16291639        }
     
    16331643
    16341644        unconst(pMedium->m->pVirtualBox) = NULL;
     1645
     1646        if (pMedium != this)
     1647            pMedium->Release();
    16351648
    16361649        autoUninitSpan.setSucceeded();
     
    42774290    bool fAdd = false;
    42784291
    4279     while (llMediaTodo.size() > 0)
     4292    while (!llMediaTodo.empty())
    42804293    {
    42814294        ComObjPtr<Medium> pMedium = llMediaTodo.front();
     
    43454358    bool fRemove = false;
    43464359
    4347     while (llMediaTodo.size() > 0)
     4360    while (!llMediaTodo.empty())
    43484361    {
    43494362        ComObjPtr<Medium> pMedium = llMediaTodo.front();
     
    46544667    llMediaTodo.push_back(this);
    46554668
    4656     while (llMediaTodo.size() > 0)
     4669    while (!llMediaTodo.empty())
    46574670    {
    46584671        const Medium *pMedium = llMediaTodo.front();
     
    50195032    llSettingsTodo.push_back(&data);
    50205033
    5021     while (llMediaTodo.size() > 0)
     5034    while (!llMediaTodo.empty())
    50225035    {
    50235036        ComObjPtr<Medium> pMedium = llMediaTodo.front();
Note: See TracChangeset for help on using the changeset viewer.

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