Err, the race in io_output() doesn't double-free
authorMarkus Armbruster <armbru@pond.sub.org>
Sun, 29 Aug 2010 09:31:02 +0000 (11:31 +0200)
committerMarkus Armbruster <armbru@pond.sub.org>
Sun, 29 Aug 2010 09:31:02 +0000 (11:31 +0200)
commit2bb8923c6f95567c75ccd7537321714e0eca6b0b
treeab1981c0075fb70738e1e9d192848c2d5cf81fa5
parentd28fbbb186b9b6e8572f89d0e3f3ab5f0c783bc5
Err, the race in io_output() doesn't double-free

The previous commit's message claims the race can lead to duplicated
output, use after free, then double-free.  That's correct only up to
the use after free.  There is no double-free.

Heap corruption (double-free?) has been observed in Changeling,
though.  Player logged in (still in sanctuary), map #, crashed within
removecc()'s free(io->data).  Partial backtrace:

    raise () from /lib64/libc.so.6
    abort () from /lib64/libc.so.6
    __libc_message () from /lib64/libc.so.6
    malloc_printerr () from /lib64/libc.so.6
    removecc (ioq=0x251fd10, cc=468) at ../src/lib/gen/ioqueue.c:350
    ioq_dequeue (ioq=0x251fd10, cc=468) at ../src/lib/gen/ioqueue.c:135
    io_output (iop=0x251fc90, wait=1) at ../src/lib/empthread/io.c:231
    recvclient (cmd=0x258d8e0 "", size=1024) at ../src/lib/player/recvclient.c:82
    getcommand (combufp=0x2557068 "map #1") at ../src/lib/player/empdis.c:84

I haven't been able to reproduce.

To hopefully catch ioqueue going south earlier, make ioq_dequeue()
oops when it can't dequeue as many bytes as requested.
src/lib/gen/ioqueue.c