Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 7

Qt-interest Archive, June 2007
QBuffer/QDataStream sanity checking


Message 1 in thread

Hi,

In my client/server application, I pass a lot of binary data back and 
forth. For this, I have functions that marshal and demarshal my internal 
datastructures to QByteArray, which in turn is sent over the network. In 
my mind, this was safe and sound.

Unfortunately, this is not the case. Just to be on the safe side, I 
tried mucking about with the transmitted data, and if the binary data 
isn't "well formed", the datastream operators do .. unexpected things.

For example:

#include <QtCore>

int main(int argc, char **argv) {
  QCoreApplication a(argc, argv);
  QByteArray qba;
  QVector<int> l,ll;

  l << 0x1234 << 0x5678;

  {
    QBuffer qbo(&qba);
    qbo.open(QBuffer::WriteOnly);

    QDataStream out(&qbo);


    out << l;
  }

  // Mess it up
  qba[0] = 1;

  for(int i=0;i<qba.size();i++)
    qWarning("Out %2d %02x", i, qba.at(i));

  {
    QBuffer qbi(&qba);
    qbi.open(QBuffer::ReadOnly);

    QDataStream in(&qbi);

    in >> ll;
  }

  for(int i=0;i<ll.size();i++)
    qWarning("Ver %2d %08x", i, ll.at(i));
}

This done on Qt 4.3.0 on RedHat 5, x86_64, g++ 4.1.1

By modifying the data, QVector happily allocates 16 million ints. Even 
if there are only room for 2 such ints in the remainder of the 
datastream. This might lead to resource starvation. However, put a 
larger number in there instead of '1', and it segfaults.

This is bad.

QList<> does not have this problem. QList allocates new entries as 
they're read, and when it reaches end of stream, it stops. QVector, to 
optimize, allocates all the data immediately. For any kind of sane 
situation, this is the correct behaviour. ... But we all know users 
aren't sane, and malicious people who would like to do nasty things to 
my application are even less so. Is there any way to make this safe 
inside the Qt framework, or do I have to write my own 
QParanoidDataStream (with the mandatory 20-ish >> and << operators)?

--
 [ signature omitted ]