Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/kraxel/tags/ui-20180216-pull-re…
Browse files Browse the repository at this point in the history
…quest' into staging

bugfixes for vnc and sdl2

# gpg: Signature made Fri 16 Feb 2018 11:53:37 GMT
# gpg:                using RSA key 4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <[email protected]>"
# gpg:                 aka "Gerd Hoffmann <[email protected]>"
# gpg:                 aka "Gerd Hoffmann (private) <[email protected]>"
# Primary key fingerprint: A032 8CFF B93A 17A7 9901  FE7D 4CB6 D8EE D3E8 7138

* remotes/kraxel/tags/ui-20180216-pull-request:
  ui: extend VNC trottling tracing to SASL codepaths
  ui: check VNC audio frequency limit at time of reading from client
  ui: avoid 'local_err' variable shadowing in VNC SASL auth
  ui: avoid risk of 32-bit int overflow in VNC buffer check
  sdl2: fix mouse grab
  sdl: restore optimized redraw
  vnc: fix segfault in closed connection handling
  vnc: add qapi/error.h include to stubs
  vnc: remove bogus object_unref on client socket

Signed-off-by: Peter Maydell <[email protected]>
  • Loading branch information
pm215 committed Feb 16, 2018
2 parents d9c92ae + d50f09f commit 5e8d6a1
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 33 deletions.
23 changes: 7 additions & 16 deletions ui/sdl2-2d.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ void sdl2_2d_update(DisplayChangeListener *dcl,
struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
DisplaySurface *surf = qemu_console_surface(dcl->con);
SDL_Rect rect;
size_t surface_data_offset = surface_bytes_per_pixel(surf) * x +
surface_stride(surf) * y;

assert(!scon->opengl);

Expand All @@ -46,27 +48,16 @@ void sdl2_2d_update(DisplayChangeListener *dcl,
return;
}

/*
* SDL2 seems to do some double-buffering, and trying to only
* update the changed areas results in only one of the two buffers
* being updated. Which flickers alot. So lets not try to be
* clever do a full update every time ...
*/
#if 0
rect.x = x;
rect.y = y;
rect.w = w;
rect.h = h;
#else
rect.x = 0;
rect.y = 0;
rect.w = surface_width(surf);
rect.h = surface_height(surf);
#endif

SDL_UpdateTexture(scon->texture, NULL, surface_data(surf),

SDL_UpdateTexture(scon->texture, &rect,
surface_data(surf) + surface_data_offset,
surface_stride(surf));
SDL_RenderCopy(scon->real_renderer, scon->texture, &rect, &rect);
SDL_RenderClear(scon->real_renderer);
SDL_RenderCopy(scon->real_renderer, scon->texture, NULL, NULL);
SDL_RenderPresent(scon->real_renderer);
}

Expand Down
1 change: 1 addition & 0 deletions ui/sdl2.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ static void sdl_mouse_mode_change(Notifier *notify, void *data)
if (qemu_input_is_absolute()) {
if (!absolute_enabled) {
absolute_enabled = 1;
SDL_SetRelativeMouseMode(SDL_FALSE);
absolute_mouse_grab(&sdl2_console[0]);
}
} else if (absolute_enabled) {
Expand Down
13 changes: 11 additions & 2 deletions ui/vnc-auth-sasl.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,23 @@ size_t vnc_client_write_sasl(VncState *vs)

vs->sasl.encodedOffset += ret;
if (vs->sasl.encodedOffset == vs->sasl.encodedLength) {
bool throttled = vs->force_update_offset != 0;
size_t offset;
if (vs->sasl.encodedRawLength >= vs->force_update_offset) {
vs->force_update_offset = 0;
} else {
vs->force_update_offset -= vs->sasl.encodedRawLength;
}
if (throttled && vs->force_update_offset == 0) {
trace_vnc_client_unthrottle_forced(vs, vs->ioc);
}
offset = vs->output.offset;
buffer_advance(&vs->output, vs->sasl.encodedRawLength);
if (offset >= vs->throttle_output_offset &&
vs->output.offset < vs->throttle_output_offset) {
trace_vnc_client_unthrottle_incremental(vs, vs->ioc,
vs->output.offset);
}
vs->sasl.encoded = NULL;
vs->sasl.encodedOffset = vs->sasl.encodedLength = 0;
}
Expand Down Expand Up @@ -556,7 +567,6 @@ void start_auth_sasl(VncState *vs)
/* Inform SASL that we've got an external SSF layer from TLS/x509 */
if (vs->auth == VNC_AUTH_VENCRYPT &&
vs->subauth == VNC_AUTH_VENCRYPT_X509SASL) {
Error *local_err = NULL;
int keysize;
sasl_ssf_t ssf;

Expand All @@ -565,7 +575,6 @@ void start_auth_sasl(VncState *vs)
if (keysize < 0) {
trace_vnc_auth_fail(vs, vs->auth, "cannot TLS get cipher size",
error_get_pretty(local_err));
error_free(local_err);
sasl_dispose(&vs->sasl.conn);
vs->sasl.conn = NULL;
goto authabort;
Expand Down
6 changes: 4 additions & 2 deletions ui/vnc-jobs.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,10 @@ void vnc_jobs_consume_buffer(VncState *vs)
if (vs->ioc_tag) {
g_source_remove(vs->ioc_tag);
}
vs->ioc_tag = qio_channel_add_watch(
vs->ioc, G_IO_IN | G_IO_OUT, vnc_client_io, vs, NULL);
if (vs->disconnecting == FALSE) {
vs->ioc_tag = qio_channel_add_watch(
vs->ioc, G_IO_IN | G_IO_OUT, vnc_client_io, vs, NULL);
}
}
buffer_move(&vs->output, &vs->jobs_buffer);

Expand Down
1 change: 1 addition & 0 deletions ui/vnc-stubs.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "qemu/osdep.h"
#include "ui/console.h"
#include "qapi/error.h"

int vnc_display_password(const char *id, const char *password)
{
Expand Down
42 changes: 29 additions & 13 deletions ui/vnc.c
Original file line number Diff line number Diff line change
Expand Up @@ -982,14 +982,7 @@ static void vnc_update_throttle_offset(VncState *vs)
vs->client_width * vs->client_height * vs->client_pf.bytes_per_pixel;

if (vs->audio_cap) {
int freq = vs->as.freq;
/* We don't limit freq when reading settings from client, so
* it could be upto MAX_INT in size. 48khz is a sensible
* upper bound for trustworthy clients */
int bps;
if (freq > 48000) {
freq = 48000;
}
switch (vs->as.fmt) {
default:
case AUD_FMT_U8:
Expand All @@ -1005,7 +998,7 @@ static void vnc_update_throttle_offset(VncState *vs)
bps = 4;
break;
}
offset += freq * bps * vs->as.nchannels;
offset += vs->as.freq * bps * vs->as.nchannels;
}

/* Put a floor of 1MB on offset, so that if we have a large pending
Expand Down Expand Up @@ -1536,12 +1529,19 @@ gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
VncState *vs = opaque;
if (condition & G_IO_IN) {
if (vnc_client_read(vs) < 0) {
return TRUE;
goto end;
}
}
if (condition & G_IO_OUT) {
vnc_client_write(vs);
}
end:
if (vs->disconnecting) {
if (vs->ioc_tag != 0) {
g_source_remove(vs->ioc_tag);
}
vs->ioc_tag = 0;
}
return TRUE;
}

Expand Down Expand Up @@ -1572,8 +1572,8 @@ void vnc_write(VncState *vs, const void *data, size_t len)
* handshake, or from the job thread's VncState clone
*/
if (vs->throttle_output_offset != 0 &&
vs->output.offset > (vs->throttle_output_offset *
VNC_THROTTLE_OUTPUT_LIMIT_SCALE)) {
(vs->output.offset / VNC_THROTTLE_OUTPUT_LIMIT_SCALE) >
vs->throttle_output_offset) {
trace_vnc_client_output_limit(vs, vs->ioc, vs->output.offset,
vs->throttle_output_offset);
vnc_disconnect_start(vs);
Expand Down Expand Up @@ -1630,6 +1630,12 @@ void vnc_flush(VncState *vs)
if (vs->ioc != NULL && vs->output.offset) {
vnc_client_write_locked(vs);
}
if (vs->disconnecting) {
if (vs->ioc_tag != 0) {
g_source_remove(vs->ioc_tag);
}
vs->ioc_tag = 0;
}
vnc_unlock_output(vs);
}

Expand Down Expand Up @@ -2279,6 +2285,7 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
{
int i;
uint16_t limit;
uint32_t freq;
VncDisplay *vd = vs->vd;

if (data[0] > 3) {
Expand Down Expand Up @@ -2398,7 +2405,17 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
vnc_client_error(vs);
break;
}
vs->as.freq = read_u32(data, 6);
freq = read_u32(data, 6);
/* No official limit for protocol, but 48khz is a sensible
* upper bound for trustworthy clients, and this limit
* protects calculations involving 'vs->as.freq' later.
*/
if (freq > 48000) {
VNC_DEBUG("Invalid audio frequency %u > 48000", freq);
vnc_client_error(vs);
break;
}
vs->as.freq = freq;
break;
default:
VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
Expand Down Expand Up @@ -3152,7 +3169,6 @@ static void vnc_listen_io(QIONetListener *listener,
isWebsock ? "vnc-ws-server" : "vnc-server");
qio_channel_set_delay(QIO_CHANNEL(cioc), false);
vnc_connect(vd, cioc, false, isWebsock);
object_unref(OBJECT(cioc));
}

static const DisplayChangeListenerOps dcl_ops = {
Expand Down

0 comments on commit 5e8d6a1

Please sign in to comment.