Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-14464

QTcpSocket accesses illegal memory location (cause segmentation fault) during changing its buffer size while writing on the socket

    XMLWordPrintable

Details

    • Bug
    • Resolution: Incomplete
    • Not Evaluated
    • None
    • 4.6.2, 4.6.3, 4.7.0, 4.7.1, 4.7.2, 4.7.3, 4.7.4
    • Core: I/O, Network
    • None
    •  - Ubuntu 2.6.35-22-generic x86_64 GNU/Linux
       - Debian 2.6.32-5-amd64 x86_64 GNU/Linux
       - Mac OS X 10.7.2 (11C74)
       - Windows 7
      Seems to be platform-independent

    Description

      There is a client/server application. The server acts as a proxy and retrieve data from another machine and pass it to its clients through QTcpSocket and the QDataStream::operator<< method. Of course the TCP socket must be able to send any kind of data. But if I run the client/server for long time (sending data for several minutes) then the program crashes while writing an "int" on the TCP socket. The new data causes socket to resize its buffer and then the crash will occur. Here is a trace of this crash:

      #0  0x00007f698b1eb94b in memcpy () from /lib/libc.so.6
      #1  0x00007f698bcfb378 in QByteArray::realloc () from /usr/lib/libQtCore.so.4
      #2  0x00007f698bcfb7b9 in QByteArray::resize () from /usr/lib/libQtCore.so.4
      #3  0x00007f698c1b73a7 in ?? () from /usr/lib/libQtNetwork.so.4
      #4  0x00007f698c1b2fae in QAbstractSocket::writeData () from /usr/lib/libQtNetwork.so.4
      #5  0x00007f698bd7ebb7 in QIODevice::write () from /usr/lib/libQtCore.so.4
      #6  0x00007f698bd6ae39 in QDataStream::operator<< () from /usr/lib/libQtCore.so.4
      #7  0x000000000042a398 in QDataStream::operator<< (this=0x7f698624a730, i=4) at /usr/include/qt4/QtCore/qdatastream.h:234
      

      I also analyzed the code using "valgrind" and it shows the illegal write as follows:

      ==6444== Invalid write of size 1
      ==6444==    at 0x4C29925: memcpy (mc_replace_strmem.c:497)
      ==6444==    by 0x57C8015: QAbstractSocket::writeData(char const*, long long) (in /usr/lib/libQtNetwork.so.4.7.0)
      ==6444==    by 0x5B364A6: QIODevice::write(char const*, long long) (in /usr/lib/libQtCore.so.4.7.0)
      ==6444==    by 0x5B21CE9: QDataStream::writeRawData(char const*, int) (in /usr/lib/libQtCore.so.4.7.0)
      

      I reproduced the issue using Qt debug build (I installed libqt4-dbg package) and this is the resulting trace:

      #0  malloc_consolidate (av=0x7fdf84000020) at malloc.c:5139
      #1  0x00007fdf8c440254 in _int_malloc (av=0x7fdf84000020, bytes=65536) at malloc.c:4373
      #2  0x00007fdf8c442930 in *__GI___libc_malloc (bytes=65536) at malloc.c:3661
      #3  0x00007fdf8cf65c28 in QByteArray::realloc (this=0x877538, alloc=<value optimized out>) at tools/qbytearray.cpp:1412
      #4  0x00007fdf8cf66099 in QByteArray::resize (this=0x877538, size=32768) at tools/qbytearray.cpp:1380
      #5  0x00007fdf8d41f527 in QRingBuffer::reserve (this=0x82aa10, bytes=4) at ../../include/QtCore/private/../../../src/corelib/tools/qringbuffer_p.h:158
      #6  0x00007fdf8d41b0fe in QAbstractSocket::writeData (this=0x86c1c0, data=0x7fdf82ffc4b0 "", size=4) at socket/qabstractsocket.cpp:2184
      #7  0x00007fdf8cfe9017 in QIODevice::write (this=0x86c1c0, data=0x7fdf82ffc4b0 "", maxSize=140597969042256) at io/qiodevice.cpp:1359
      #8  0x00007fdf8cfd5809 in QDataStream::operator<< (this=0x7fdf82ffc510, i=4) at io/qdatastream.cpp:1125
      #9  0x000000000042a4b8 in QDataStream::operator<< (this=0x7fdf82ffc510, i=4) at /usr/include/qt4/QtCore/qdatastream.h:234
      

      The program could get and pass data on the socket for several minutes before crashing.

      UPDATE: A test case is attached for reproducing this issue. In the attached archive, you can find two folders, tcpclient and tcpserver. In each folder use "qmake" and "make" for compiling them. Then first run tcpserver and then run tcpclient with IP address of server as its argument. I can reproduce the crash on one machine by running programs as:

      ./tcpserver
      
      ./tcpclient 127.0.0.1
      

      The test case tries to transfer data back and forth between client and server programs as fast as possible and also tries to change its sending rate randomly to stress the memory usage.

      It crashes on one machine within about 10 minutes.
      But it's a little random; it sometimes crashes in less than 5 minutes and sometimes it does not crash for a long time (if it did not crash soon, in about 15 minutes, kill it and run it again). It may also be killed if memory (OS buffer) get filled completely. In this case, simply run it again.

      If you need any more information for locating the bug, just
      ask.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            Unassigned Unassigned
            momeni Behnam Momeni
            Votes:
            5 Vote for this issue
            Watchers:
            11 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes