Re: [PATCH spice 4/8 v2] Receive the GraphicsDeviceInfo message from the streaming agent

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 2019-01-15 at 08:31 -0500, Frediano Ziglio wrote:
> > 
> > Receives the GraphicsDeviceInfo message from the streaming agent and
> > stores the data in a list on the streaming device.
> > 
> > Signed-off-by: Lukáš Hrázký <lhrazky@xxxxxxxxxx>
> > ---
> >  server/display-limits.h    |  3 ++
> >  server/red-qxl.c           |  2 +-
> >  server/red-stream-device.c | 67 ++++++++++++++++++++++++++++++++++++--
> >  server/red-stream-device.h |  8 +++++
> >  server/reds.c              |  1 +
> >  5 files changed, 78 insertions(+), 3 deletions(-)
> > 
> > diff --git a/server/display-limits.h b/server/display-limits.h
> > index e875149b..d79d3211 100644
> > --- a/server/display-limits.h
> > +++ b/server/display-limits.h
> > @@ -25,4 +25,7 @@
> >  /** Maximum number of streams created by spice-server */
> >  #define NUM_STREAMS 50
> >  
> > +/** Maximum length of the device address string */
> > +#define MAX_DEVICE_ADDRESS_LEN 256
> > +
> >  #endif /* DISPLAY_LIMITS_H_ */
> > diff --git a/server/red-qxl.c b/server/red-qxl.c
> > index a56d9a52..943ccb08 100644
> > --- a/server/red-qxl.c
> > +++ b/server/red-qxl.c
> > @@ -37,11 +37,11 @@
> >  #include "dispatcher.h"
> >  #include "red-parse-qxl.h"
> >  #include "red-channel-client.h"
> > +#include "display-limits.h"
> >  
> >  #include "red-qxl.h"
> >  
> >  
> > -#define MAX_DEVICE_ADDRESS_LEN 256
> >  #define MAX_MONITORS_COUNT 16
> >  
> >  struct QXLState {
> > diff --git a/server/red-stream-device.c b/server/red-stream-device.c
> > index 215ddbe7..20bf115d 100644
> > --- a/server/red-stream-device.c
> > +++ b/server/red-stream-device.c
> > @@ -37,6 +37,7 @@ struct StreamDevice {
> >          StreamMsgCapabilities capabilities;
> >          StreamMsgCursorSet cursor_set;
> >          StreamMsgCursorMove cursor_move;
> > +        StreamMsgDeviceDisplayInfo device_display_info;
> >          uint8_t buf[STREAM_MSG_CAPABILITIES_MAX_BYTES];
> >      } *msg;
> >      uint32_t msg_pos;
> > @@ -49,6 +50,7 @@ struct StreamDevice {
> >      CursorChannel *cursor_channel;
> >      SpiceTimer *close_timer;
> >      uint32_t frame_mmtime;
> > +    StreamDeviceDisplayInfo device_display_info;
> >  };
> >  
> >  struct StreamDeviceClass {
> > @@ -64,8 +66,8 @@ static void char_device_set_state(RedCharDevice *char_dev,
> > int state);
> >  typedef bool StreamMsgHandler(StreamDevice *dev, SpiceCharDeviceInstance
> >  *sin)
> >      SPICE_GNUC_WARN_UNUSED_RESULT;
> >  
> > -static StreamMsgHandler handle_msg_format, handle_msg_data,
> > handle_msg_cursor_set,
> > -    handle_msg_cursor_move, handle_msg_capabilities;
> > +static StreamMsgHandler handle_msg_format, handle_msg_device_display_info,
> > handle_msg_data,
> > +    handle_msg_cursor_set, handle_msg_cursor_move, handle_msg_capabilities;
> >  
> >  static bool handle_msg_invalid(StreamDevice *dev, SpiceCharDeviceInstance
> >  *sin,
> >                                 const char *error_msg)
> >                                 SPICE_GNUC_WARN_UNUSED_RESULT;
> > @@ -146,6 +148,13 @@ stream_device_partial_read(StreamDevice *dev,
> > SpiceCharDeviceInstance *sin)
> >              handled = handle_msg_format(dev, sin);
> >          }
> >          break;
> > +    case STREAM_TYPE_DEVICE_DISPLAY_INFO:
> > +        if (dev->hdr.size > sizeof(StreamMsgDeviceDisplayInfo) +
> > MAX_DEVICE_ADDRESS_LEN) {
> > +            handled = handle_msg_invalid(dev, sin,
> > "StreamMsgDeviceDisplayInfo too large");
> > +        } else {
> > +            handled = handle_msg_device_display_info(dev, sin);
> > +        }
> > +        break;
> >      case STREAM_TYPE_DATA:
> >          if (dev->hdr.size > 32*1024*1024) {
> >              handled = handle_msg_invalid(dev, sin, "STREAM_DATA too large");
> > @@ -271,6 +280,60 @@ handle_msg_format(StreamDevice *dev,
> > SpiceCharDeviceInstance *sin)
> >      return true;
> >  }
> >  
> > +static bool
> > +handle_msg_device_display_info(StreamDevice *dev, SpiceCharDeviceInstance
> > *sin)
> > +{
> > +    SpiceCharDeviceInterface *sif = spice_char_device_get_interface(sin);
> > +
> > +    if (spice_extra_checks) {
> > +        spice_assert(dev->hdr_pos >= sizeof(StreamDevHeader));
> > +        spice_assert(dev->hdr.type == STREAM_TYPE_DEVICE_DISPLAY_INFO);
> > +    }
> > +
> > +    if (dev->msg_len < dev->hdr.size) {
> > +        dev->msg = g_realloc(dev->msg, dev->hdr.size);
> > +        dev->msg_len = dev->hdr.size;
> > +    }
> > +
> > +    /* read from device */
> > +    ssize_t n = sif->read(sin, dev->msg->buf + dev->msg_pos, dev->hdr.size -
> > dev->msg_pos);
> > +    if (n <= 0) {
> > +        return dev->msg_pos == dev->hdr.size;
> > +    }
> > +
> > +    dev->msg_pos += n;
> > +    if (dev->msg_pos != dev->hdr.size) { /* some bytes are still missing */
> > +        return false;
> > +    }
> > +
> > +    StreamMsgDeviceDisplayInfo *display_info_msg =
> > &dev->msg->device_display_info;
> > +
> > +    size_t device_address_len =
> > GUINT32_FROM_LE(display_info_msg->device_address_len);
> > +    if (device_address_len > MAX_DEVICE_ADDRESS_LEN) {
> > +        g_error("Received a device address longer than %u (%zu), "
> > +                "will be truncated!", MAX_DEVICE_ADDRESS_LEN,
> > device_address_len);
> 
> DoS, g_error will abort() Qemu.

I'll put a warning there, though I think it should be logged as an
error...

> > +        device_address_len =
> > sizeof(dev->device_display_info.device_address);
> > +    }
> > +
> > +    strncpy(dev->device_display_info.device_address,
> > +            (char*) display_info_msg->device_address,
> > +            device_address_len);
> 
> buffer overflow reading, is not guaranteed that the address
> fit in the message, you need to check it.

Right, I'll fix it.

> > +
> > +    // make sure the string is terminated
> > +    dev->device_display_info.device_address[device_address_len - 1] = '\0';
> > +
> 
> buffer overflow writing if devide_address_len is 0, also device_address won't
> be terminated causing a future buffer overflow reading.

Same here. Similar problem in vd_agent, I'll fix that as well.

> > +    dev->device_display_info.stream_id =
> > GUINT32_FROM_LE(display_info_msg->stream_id);
> > +    dev->device_display_info.device_display_id =
> > GUINT32_FROM_LE(display_info_msg->device_display_id);
> > +
> > +    g_debug("Received DeviceDisplayInfo from the streaming agent: stream_id
> > %u, "
> > +            "device_address %s, device_display_id %u",
> > +            dev->device_display_info.stream_id,
> > +            dev->device_display_info.device_address,
> > +            dev->device_display_info.device_display_id);
> > +
> > +    return true;
> > +}
> > +
> >  static bool
> >  handle_msg_capabilities(StreamDevice *dev, SpiceCharDeviceInstance *sin)
> >  {
> > diff --git a/server/red-stream-device.h b/server/red-stream-device.h
> > index f0a5b5c1..996be016 100644
> > --- a/server/red-stream-device.h
> > +++ b/server/red-stream-device.h
> > @@ -19,6 +19,7 @@
> >  #ifndef STREAM_DEVICE_H
> >  #define STREAM_DEVICE_H
> >  
> > +#include "display-limits.h"
> >  #include "char-device.h"
> >  
> >  G_BEGIN_DECLS
> > @@ -41,6 +42,13 @@ typedef struct StreamDeviceClass StreamDeviceClass;
> >      (G_TYPE_INSTANCE_GET_CLASS((obj), TYPE_STREAM_DEVICE,
> >      StreamDeviceClass))
> >  
> >  GType stream_device_get_type(void) G_GNUC_CONST;
> > +
> > +typedef struct StreamDeviceDisplayInfo {
> > +    uint32_t stream_id;
> > +    char device_address[MAX_DEVICE_ADDRESS_LEN];
> > +    uint32_t device_display_id;
> > +} StreamDeviceDisplayInfo;
> > +
> >  StreamDevice *stream_device_connect(RedsState *reds, SpiceCharDeviceInstance
> >  *sin);
> >  
> >  /* Create channel for the streaming device.
> > diff --git a/server/reds.c b/server/reds.c
> > index 88a82419..48796ba6 100644
> > --- a/server/reds.c
> > +++ b/server/reds.c
> > @@ -74,6 +74,7 @@
> >  #include "glib-compat.h"
> >  #include "net-utils.h"
> >  #include "red-stream-device.h"
> > +#include "display-limits.h"
> 
> This should not be necessary.

True, removing it.

Thanks,
Lukas

> >  
> >  #define REDS_MAX_STAT_NODES 100
> >  
> 
> Frediano
_______________________________________________
Spice-devel mailing list
Spice-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/spice-devel




[Index of Archives]     [Linux Virtualization]     [Linux Virtualization]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]     [Monitors]