summary refs log tree commit diff stats
path: root/chardev/char-socket.c
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@redhat.com>2020-04-20 13:20:12 +0200
committerMarc-André Lureau <marcandre.lureau@redhat.com>2020-07-13 11:59:47 +0400
commit6806601969a0d6c095e3836423fef1dedec55289 (patch)
treed280ebc01c64f9583457a0651606ebc9870ac0c2 /chardev/char-socket.c
parent14a7a203063694ff932f3371ed93e97987dcafc0 (diff)
downloadfocaccia-qemu-6806601969a0d6c095e3836423fef1dedec55289.tar.gz
focaccia-qemu-6806601969a0d6c095e3836423fef1dedec55289.zip
char: fix use-after-free with dup chardev & reconnect
With a reconnect socket, qemu_char_open() will start a background
thread. It should keep a reference on the chardev.

Fixes invalid read:
READ of size 8 at 0x6040000ac858 thread T7
    #0 0x5555598d37b8 in unix_connect_saddr /home/elmarco/src/qq/util/qemu-sockets.c:954
    #1 0x5555598d4751 in socket_connect /home/elmarco/src/qq/util/qemu-sockets.c:1109
    #2 0x555559707c34 in qio_channel_socket_connect_sync /home/elmarco/src/qq/io/channel-socket.c:145
    #3 0x5555596adebb in tcp_chr_connect_client_task /home/elmarco/src/qq/chardev/char-socket.c:1104
    #4 0x555559723d55 in qio_task_thread_worker /home/elmarco/src/qq/io/task.c:123
    #5 0x5555598a6731 in qemu_thread_start /home/elmarco/src/qq/util/qemu-thread-posix.c:519
    #6 0x7ffff40d4431 in start_thread (/lib64/libpthread.so.0+0x9431)
    #7 0x7ffff40029d2 in __clone (/lib64/libc.so.6+0x1019d2)

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Message-Id: <20200420112012.567284-1-marcandre.lureau@redhat.com>
Diffstat (limited to 'chardev/char-socket.c')
-rw-r--r--chardev/char-socket.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 320aa7c642..ef62dbf3d7 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -1129,7 +1129,8 @@ static void tcp_chr_connect_client_async(Chardev *chr)
      */
     s->connect_task = qio_task_new(OBJECT(sioc),
                                    qemu_chr_socket_connected,
-                                   chr, NULL);
+                                   object_ref(OBJECT(chr)),
+                                   (GDestroyNotify)object_unref);
     qio_task_run_in_thread(s->connect_task,
                            tcp_chr_connect_client_task,
                            s->addr,