diff options
author | Marc-André Lureau <marcandre.lureau@redhat.com> | 2011-03-03 13:56:00 +0100 |
---|---|---|
committer | Marc-André Lureau <marcandre.lureau@redhat.com> | 2011-03-03 14:59:31 +0100 |
commit | 17096d1dc8f5abb703149fe6dcd92d41f3c3d4dc (patch) | |
tree | eaf2916815a211fdbea1e03343394ed27cfec9b5 /server/inputs_channel.c | |
parent | 28f30071452af808c3d3fc18df654755d8ab523c (diff) | |
download | spice-17096d1dc8f5abb703149fe6dcd92d41f3c3d4dc.tar.gz spice-17096d1dc8f5abb703149fe6dcd92d41f3c3d4dc.tar.xz spice-17096d1dc8f5abb703149fe6dcd92d41f3c3d4dc.zip |
server/input: avoid double free() of RedChannel on disconnect
Current master is calling red_channel_destroy() on incoming error, but
reds Channels still references it, which causes a double free() later
on (see valgrind report below).
Instead, on error condition, do like the rest of the channels and call
reds_disconnect(), which remove the references and call shutdown(),
which then call red_channel_destroy() and finally free the channel
with red_channel_destroy().
Note: the previous code intention was certainly to be able to keep the
rest of the channels connected when input channel has errors. This is
not addressed by this patch.
red_channel_shutdown:
==29792== Invalid read of size 8
==29792== at 0x4C6F063: red_channel_shutdown (red_channel.c:460)
==29792== by 0x4C51EFA: inputs_shutdown (inputs_channel.c:463)
==29792== by 0x4C48445: reds_shatdown_channels (reds.c:539)
==29792== by 0x4C4868A: reds_disconnect (reds.c:603)
==29792== by 0x4C519E9: main_channel_on_error (main_channel.c:765)
==29792== by 0x4C6E80A: red_channel_peer_on_incoming_error (red_channel.c:215)
==29792== by 0x4C6E22D: red_peer_handle_incoming (red_channel.c:87)
==29792== by 0x4C6E551: red_channel_receive (red_channel.c:154)
==29792== by 0x4C6F329: red_channel_event (red_channel.c:531)
==29792== by 0x41CB8C: main_loop_wait (vl.c:1365)
==29792== by 0x437CDE: kvm_main_loop (qemu-kvm.c:1589)
==29792== by 0x41FE9A: main (vl.c:1411)
==29792== Address 0x30b0f6d0 is 0 bytes inside a block of size 28,648 free'd
==29792== at 0x4A05372: free (vg_replace_malloc.c:366)
==29792== by 0x4C6F032: red_channel_destroy (red_channel.c:454)
==29792== by 0x4C6E80A: red_channel_peer_on_incoming_error (red_channel.c:215)
==29792== by 0x4C6E22D: red_peer_handle_incoming (red_channel.c:87)
==29792== by 0x4C6E551: red_channel_receive (red_channel.c:154)
==29792== by 0x4C6F329: red_channel_event (red_channel.c:531)
==29792== by 0x41CB8C: main_loop_wait (vl.c:1365)
==29792== by 0x437CDE: kvm_main_loop (qemu-kvm.c:1589)
==29792== by 0x41FE9A: main (vl.c:1411)
https://bugs.freedesktop.org/show_bug.cgi?id=34971
Diffstat (limited to 'server/inputs_channel.c')
-rw-r--r-- | server/inputs_channel.c | 12 |
1 files changed, 4 insertions, 8 deletions
diff --git a/server/inputs_channel.c b/server/inputs_channel.c index d6bcf9de..213f8a0b 100644 --- a/server/inputs_channel.c +++ b/server/inputs_channel.c @@ -443,14 +443,9 @@ static void inputs_relase_keys(void) kbd_push_scan(keyboard, 0x38 | 0x80); //LALT } -static void inputs_channel_on_incoming_error(RedChannel *channel) +static void inputs_channel_on_error(RedChannel *channel) { inputs_relase_keys(); - red_channel_destroy(channel); -} - -static void inputs_channel_on_outgoing_error(RedChannel *channel) -{ reds_disconnect(); } @@ -461,6 +456,7 @@ static void inputs_shutdown(Channel *channel) if (inputs_channel) { red_channel_shutdown(&inputs_channel->base); + red_channel_destroy(&inputs_channel->base); channel->data = NULL; g_inputs_channel = NULL; } @@ -528,8 +524,8 @@ static void inputs_link(Channel *channel, RedsStream *stream, int migration, ,inputs_channel_hold_pipe_item ,inputs_channel_send_item ,inputs_channel_release_pipe_item - ,inputs_channel_on_incoming_error - ,inputs_channel_on_outgoing_error + ,inputs_channel_on_error + ,inputs_channel_on_error ,NULL ,NULL ,NULL); |