summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathon Jongsma <jjongsma@redhat.com>2017-11-15 14:04:33 -0600
committerFrediano Ziglio <fziglio@redhat.com>2017-11-27 21:37:53 +0000
commit61aa6ac8aa150392c849ac76e2d226973d57ff0f (patch)
tree377d4d8df6a36e74760bc45a981a024a1c67415e
parent49234be2dd9940eb18728eaac2c5990cbfd9c667 (diff)
StreamDevice: Handle incomplete reads of StreamMsgFormat
This is currently unlikely to happen since we communicate over a pipe and the pipe buffer is sufficiently large to avoid splitting the message. But for completeness, we should handle this scenario. Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> Acked-by: Frediano Ziglio <fziglio@redhat.com>
-rw-r--r--configure.ac2
-rw-r--r--server/stream-device.c32
2 files changed, 24 insertions, 10 deletions
diff --git a/configure.ac b/configure.ac
index fb266ad4..3401dba8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -156,7 +156,7 @@ AS_IF([test x"$have_smartcard" = "xyes"], [
AS_VAR_APPEND([SPICE_REQUIRES], [" libcacard >= 0.1.2"])
])
-SPICE_PROTOCOL_MIN_VER=0.12.13
+SPICE_PROTOCOL_MIN_VER=0.12.14
PKG_CHECK_MODULES([SPICE_PROTOCOL], [spice-protocol >= $SPICE_PROTOCOL_MIN_VER])
AC_SUBST([SPICE_PROTOCOL_MIN_VER])
diff --git a/server/stream-device.c b/server/stream-device.c
index fc5b5065..0953a6d0 100644
--- a/server/stream-device.c
+++ b/server/stream-device.c
@@ -42,6 +42,12 @@ struct StreamDevice {
StreamDevHeader hdr;
uint8_t hdr_pos;
+ union {
+ StreamMsgFormat format;
+ StreamMsgCapabilities capabilities;
+ uint8_t buf[STREAM_MSG_CAPABILITIES_MAX_BYTES];
+ } msg;
+ uint32_t msg_pos;
bool has_error;
bool opened;
bool flow_stopped;
@@ -89,6 +95,7 @@ stream_device_read_msg_from_dev(RedCharDevice *self, SpiceCharDeviceInstance *si
if (dev->hdr_pos >= sizeof(dev->hdr)) {
dev->hdr.type = GUINT16_FROM_LE(dev->hdr.type);
dev->hdr.size = GUINT32_FROM_LE(dev->hdr.size);
+ dev->msg_pos = 0;
}
}
@@ -155,19 +162,25 @@ handle_msg_invalid(StreamDevice *dev, SpiceCharDeviceInstance *sin, const char *
static bool
handle_msg_format(StreamDevice *dev, SpiceCharDeviceInstance *sin)
{
- StreamMsgFormat fmt;
SpiceCharDeviceInterface *sif = spice_char_device_get_interface(sin);
- int n = sif->read(sin, (uint8_t *) &fmt, sizeof(fmt));
- if (n == 0) {
- return false;
- }
- if (n != sizeof(fmt)) {
+
+ spice_assert(dev->hdr_pos >= sizeof(StreamDevHeader));
+ spice_assert(dev->hdr.type == STREAM_TYPE_FORMAT);
+
+ int n = sif->read(sin, dev->msg.buf + dev->msg_pos, sizeof(StreamMsgFormat) - dev->msg_pos);
+ if (n < 0) {
return handle_msg_invalid(dev, sin, NULL);
}
- fmt.width = GUINT32_FROM_LE(fmt.width);
- fmt.height = GUINT32_FROM_LE(fmt.height);
- stream_channel_change_format(dev->stream_channel, &fmt);
+ dev->msg_pos += n;
+
+ if (dev->msg_pos < sizeof(StreamMsgFormat)) {
+ return false;
+ }
+
+ dev->msg.format.width = GUINT32_FROM_LE(dev->msg.format.width);
+ dev->msg.format.height = GUINT32_FROM_LE(dev->msg.format.height);
+ stream_channel_change_format(dev->stream_channel, &dev->msg.format);
return true;
}
@@ -334,6 +347,7 @@ stream_device_port_event(RedCharDevice *char_dev, uint8_t event)
allocate_channels(dev);
}
dev->hdr_pos = 0;
+ dev->msg_pos = 0;
dev->has_error = false;
dev->flow_stopped = false;
red_char_device_reset(char_dev);