Compare commits

...

3 Commits

Author SHA1 Message Date
Daniel P. Berrange
ea69744988 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>
2016-07-12 08:34:13 +02:00
Peter Lieven
095497ffc6 vnc-enc-tight: use thread local storage for palette
currently the color counting palette is allocated from heap, used and destroyed
for each single subrect. Use a static palette per thread for this purpose and
avoid the malloc and free for each update.

Signed-off-by: Peter Lieven <pl@kamp.de>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-id: 1467280846-9674-1-git-send-email-pl@kamp.de
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2016-07-12 08:34:13 +02:00
Gonglei
5a693efda8 vnc: fix incorrect checking condition when updating client
vs->disconnecting is set to TRUE and vs->ioc is closed, but
vs->ioc isn't set to NULL, so that the vnc_disconnect_finish()
isn't invoked when you update client in vnc_update_client()
after vnc_disconnect_start invoked. Let's using change the checking
condition to avoid resource leak.

Signed-off-by: Haibin Wang <wanghaibin.wang@huawei.com>
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
Message-id: 1467949056-81208-1-git-send-email-arei.gonglei@huawei.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2016-07-12 08:34:13 +02:00
2 changed files with 22 additions and 16 deletions

View File

@@ -349,7 +349,7 @@ tight_detect_smooth_image(VncState *vs, int w, int h)
tight_fill_palette##bpp(VncState *vs, int x, int y, \
int max, size_t count, \
uint32_t *bg, uint32_t *fg, \
VncPalette **palette) { \
VncPalette *palette) { \
uint##bpp##_t *data; \
uint##bpp##_t c0, c1, ci; \
int i, n0, n1; \
@@ -396,23 +396,23 @@ tight_detect_smooth_image(VncState *vs, int w, int h)
return 0; \
} \
\
*palette = palette_new(max, bpp); \
palette_put(*palette, c0); \
palette_put(*palette, c1); \
palette_put(*palette, ci); \
palette_init(palette, max, bpp); \
palette_put(palette, c0); \
palette_put(palette, c1); \
palette_put(palette, ci); \
\
for (i++; i < count; i++) { \
if (data[i] == ci) { \
continue; \
} else { \
ci = data[i]; \
if (!palette_put(*palette, (uint32_t)ci)) { \
if (!palette_put(palette, (uint32_t)ci)) { \
return 0; \
} \
} \
} \
\
return palette_size(*palette); \
return palette_size(palette); \
}
DEFINE_FILL_PALETTE_FUNCTION(8)
@@ -421,7 +421,7 @@ DEFINE_FILL_PALETTE_FUNCTION(32)
static int tight_fill_palette(VncState *vs, int x, int y,
size_t count, uint32_t *bg, uint32_t *fg,
VncPalette **palette)
VncPalette *palette)
{
int max;
@@ -1457,9 +1457,11 @@ static int send_sub_rect_jpeg(VncState *vs, int x, int y, int w, int h,
}
#endif
static __thread VncPalette color_count_palette;
static int send_sub_rect(VncState *vs, int x, int y, int w, int h)
{
VncPalette *palette = NULL;
VncPalette *palette = &color_count_palette;
uint32_t bg = 0, fg = 0;
int colors;
int ret = 0;
@@ -1488,7 +1490,7 @@ static int send_sub_rect(VncState *vs, int x, int y, int w, int h)
}
#endif
colors = tight_fill_palette(vs, x, y, w * h, &bg, &fg, &palette);
colors = tight_fill_palette(vs, x, y, w * h, &bg, &fg, palette);
#ifdef CONFIG_VNC_JPEG
if (allow_jpeg && vs->tight.quality != (uint8_t)-1) {
@@ -1501,7 +1503,6 @@ static int send_sub_rect(VncState *vs, int x, int y, int w, int h)
ret = send_sub_rect_nojpeg(vs, x, y, w, h, bg, fg, colors, palette);
#endif
palette_destroy(palette);
return ret;
}

View File

@@ -1025,7 +1025,7 @@ static int find_and_clear_dirty_height(VncState *vs,
static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
{
vs->has_dirty += has_dirty;
if (vs->need_update && vs->ioc != NULL) {
if (vs->need_update && !vs->disconnecting) {
VncDisplay *vd = vs->vd;
VncJob *job;
int y;
@@ -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);