mirror of
https://github.com/xemu-project/xemu.git
synced 2025-02-12 07:32:19 +00:00
ui: avoid crash if vnc client disconnects with writes pending
The vnc_client_read() function is called from the vnc_client_io() event handler callback when there is incoming data to process. If it detects that the client has disconnected, then it will trigger cleanup and free'ing of the VncState client struct at a safe time. Unfortunately, the vnc_client_io() event handler will also call vnc_client_write() to handle any outgoing data writes. So if vnc_client_io() was invoked with both G_IO_IN and G_IO_OUT events set, and the client disconnects, we may try to write to a client which has just been freed. https://bugs.launchpad.net/qemu/+bug/1594861 Signed-off-by: Daniel P. Berrange <berrange@redhat.com> Message-id: 1467042529-3372-1-git-send-email-berrange@redhat.com Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
095497ffc6
commit
ea69744988
13
ui/vnc.c
13
ui/vnc.c
@ -1436,8 +1436,9 @@ static void vnc_jobs_bh(void *opaque)
|
||||
* First function called whenever there is more data to be read from
|
||||
* the client socket. Will delegate actual work according to whether
|
||||
* SASL SSF layers are enabled (thus requiring decryption calls)
|
||||
* Returns 0 on success, -1 if client disconnected
|
||||
*/
|
||||
static void vnc_client_read(VncState *vs)
|
||||
static int vnc_client_read(VncState *vs)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
@ -1450,8 +1451,9 @@ static void vnc_client_read(VncState *vs)
|
||||
if (!ret) {
|
||||
if (vs->disconnecting) {
|
||||
vnc_disconnect_finish(vs);
|
||||
return -1;
|
||||
}
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
|
||||
@ -1461,7 +1463,7 @@ static void vnc_client_read(VncState *vs)
|
||||
ret = vs->read_handler(vs, vs->input.buffer, len);
|
||||
if (vs->disconnecting) {
|
||||
vnc_disconnect_finish(vs);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
@ -1470,6 +1472,7 @@ static void vnc_client_read(VncState *vs)
|
||||
vs->read_handler_expect = ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
|
||||
@ -1477,7 +1480,9 @@ gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
|
||||
{
|
||||
VncState *vs = opaque;
|
||||
if (condition & G_IO_IN) {
|
||||
vnc_client_read(vs);
|
||||
if (vnc_client_read(vs) < 0) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
if (condition & G_IO_OUT) {
|
||||
vnc_client_write(vs);
|
||||
|
Loading…
x
Reference in New Issue
Block a user