Fix undefined behavior: accessing an object after destruction

QDBusConnectionPrivate keeps a pointer to a QDBusConnectionInterface,
which in turn holds a reference back to that QDBusConnectionPrivate.
During the interface object's destruction, the QDBusAbstractInterface's
destructor checks if the interface is still valid. That access is
undefined behavior, but has so far been benign in all our uses since
the memory had not yet been freed (just destroyed) and the reference
count went from 0 to -1.

To be on the safe side, we destroy now the QDBusConnectionInterface
object while the Private is still valid. It will bring the reference
count down from 0 to a negative number, but won't cause any other
effects.

Change-Id: I9a75ad8521ae4e5cbbe5ffff13d1b80057e13809
Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
bb10
Thiago Macieira 2015-04-03 22:21:08 -07:00
parent 2bcbe227bd
commit d370878aa0
2 changed files with 10 additions and 0 deletions

View File

@ -1038,6 +1038,15 @@ QDBusConnectionPrivate::~QDBusConnectionPrivate()
"Timer and socket errors will follow and the program will probably crash",
qPrintable(name));
if (mode == ClientMode) {
// the bus service object holds a reference back to us;
// we need to destroy it before we finish destroying ourselves
Q_ASSERT(ref.load() == 0);
QObject *obj = (QObject *)busService;
disconnect(obj, Q_NULLPTR, this, Q_NULLPTR);
delete obj;
}
closeConnection();
rootNode.children.clear(); // free resources
qDeleteAll(cachedMetaObjects);

View File

@ -111,6 +111,7 @@ QDBusServer::~QDBusServer()
}
d->serverConnectionNames.clear();
}
d->ref.store(0);
d->deleteLater();
}