diff options
author | Sami Rosendahl <ext-sami.1.rosendahl@nokia.com> | 2011-11-30 19:36:56 (GMT) |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@nokia.com> | 2011-11-30 19:38:30 (GMT) |
commit | e20eaed5c1968e32eca97cf449fa588cfab35a5d (patch) | |
tree | fae8b740521b9e5fb1c530d9c9a5215201a4ad80 /tests/auto/qdbusmarshall | |
parent | 27c322e0f88fa0cccba8cf914655cacb5dae51de (diff) | |
download | Qt-e20eaed5c1968e32eca97cf449fa588cfab35a5d.zip Qt-e20eaed5c1968e32eca97cf449fa588cfab35a5d.tar.gz Qt-e20eaed5c1968e32eca97cf449fa588cfab35a5d.tar.bz2 |
Fix stack overwrite in QDBusDemarshaller
QDBusArgument extraction operators and QDBusDemarshaller that implements
the extraction do not check the type of the extracted value.
Helper function template qIterGet in qdbusdemarshaller.cpp that is used
for extracting basic data types only reserves space from the stack for
the expected type as specified by client.
If the actual type in the DBus parameter is larger stack will be
overwritten in the helper function by at most 7 bytes (expected one byte,
received dbus_uint_64_t of size 8 bytes).
The fix always reserves space for the largest basic type dbus_uint64_t
readable by dbus_message_iter_get_basic API.
See also http://dbus.freedesktop.org/doc/api/html/group__DBusMessage.html#ga41c23a05e552d0574d0444d4693d18ab
PMO 280456
Task-number: QTBUG-22735
Merge-request: 1469
Reviewed-by: thiago
Diffstat (limited to 'tests/auto/qdbusmarshall')
-rw-r--r-- | tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp index cca212e..9754a84 100644 --- a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp +++ b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp @@ -93,6 +93,9 @@ private slots: void receiveUnknownType_data(); void receiveUnknownType(); + void demarshallPrimitives_data(); + void demarshallPrimitives(); + private: int fileDescriptorForTest(); @@ -1168,5 +1171,84 @@ void tst_QDBusMarshall::receiveUnknownType() #endif } +void tst_QDBusMarshall::demarshallPrimitives_data() +{ + sendBasic_data(); +} + +template<class T> +QVariant demarshallPrimitiveAs(const QDBusArgument& dbusArg) +{ + T val; + dbusArg >> val; + return qVariantFromValue(val); +} + +QVariant demarshallPrimitiveAs(int typeIndex, const QDBusArgument& dbusArg) +{ + switch (typeIndex) { + case 0: + return demarshallPrimitiveAs<uchar>(dbusArg); + case 1: + return demarshallPrimitiveAs<bool>(dbusArg); + case 2: + return demarshallPrimitiveAs<short>(dbusArg); + case 3: + return demarshallPrimitiveAs<ushort>(dbusArg); + case 4: + return demarshallPrimitiveAs<int>(dbusArg); + case 5: + return demarshallPrimitiveAs<uint>(dbusArg); + case 6: + return demarshallPrimitiveAs<qlonglong>(dbusArg); + case 7: + return demarshallPrimitiveAs<qulonglong>(dbusArg); + case 8: + return demarshallPrimitiveAs<double>(dbusArg); + default: + return QVariant(); + } +} + +void tst_QDBusMarshall::demarshallPrimitives() +{ + QFETCH(QVariant, value); + QFETCH(QString, sig); + + QDBusConnection con = QDBusConnection::sessionBus(); + + QVERIFY(con.isConnected()); + + // Demarshall each test data value to all primitive types to test + // demarshalling to the wrong type does not cause a crash + for (int typeIndex = 0; true; ++typeIndex) { + QDBusMessage msg = QDBusMessage::createMethodCall(serviceName, objectPath, + interfaceName, "ping"); + QDBusArgument sendArg; + sendArg.beginStructure(); + sendArg.appendVariant(value); + sendArg.endStructure(); + msg.setArguments(QVariantList() << qVariantFromValue(sendArg)); + QDBusMessage reply = con.call(msg); + + const QDBusArgument receiveArg = qvariant_cast<QDBusArgument>(reply.arguments().at(0)); + receiveArg.beginStructure(); + QCOMPARE(receiveArg.currentSignature(), sig); + + const QVariant receiveValue = demarshallPrimitiveAs(typeIndex, receiveArg); + if (receiveValue.type() == value.type()) { + // Value type is the same, compare the values + QCOMPARE(receiveValue, value); + QVERIFY(receiveArg.atEnd()); + } + + receiveArg.endStructure(); + QVERIFY(receiveArg.atEnd()); + + if (!receiveValue.isValid()) + break; + } +} + QTEST_MAIN(tst_QDBusMarshall) #include "tst_qdbusmarshall.moc" |