Skip to content
Snippets Groups Projects
  1. Oct 03, 2023
  2. Mar 13, 2023
  3. Apr 27, 2022
  4. May 21, 2021
  5. Mar 15, 2021
    • Daniel P. Berrangé's avatar
      ui: honour the actual guest display dimensions without rounding · 69cc8db4
      Daniel P. Berrangé authored
      
      A long time ago the VNC server code had some memory corruption
      fixes done in:
      
        commit bea60dd7
        Author: Peter Lieven <pl@kamp.de>
        Date:   Mon Jun 30 10:57:51 2014 +0200
      
          ui/vnc: fix potential memory corruption issues
      
      One of the implications of the fix was that the VNC server would have a
      thin black bad down the right hand side if the guest desktop width was
      not a multiple of 16. In practice this was a non-issue since the VNC
      server was always honouring a guest specified resolution and guests
      essentially always pick from a small set of sane resolutions likely in
      real world hardware.
      
      We recently introduced support for the extended desktop resize extension
      and as a result the VNC client has ability to specify an arbitrary
      desktop size and the guest OS may well honour it exactly. As a result we
      no longer have any guarantee that the width will be a multiple of 16,
      and so when resizing the desktop we have a 93% chance of getting the
      black bar on the right hand size.
      
      The VNC server maintains three different desktop dimensions
      
       1. The guest surface
       2. The server surface
       3. The client desktop
      
      The requirement for the width to be a multiple of 16 only applies to
      item 2, the server surface, for the purpose of doing dirty bitmap
      tracking.
      
      Normally we will set the client desktop size to always match the server
      surface size, but that's not a strict requirement. In order to cope with
      clients that don't support the desktop size encoding, we already allow
      for the client desktop to be a different size that the server surface.
      
      Thus we can trivially eliminate the black bar, but setting the client
      desktop size to be the un-rounded server surface size - the so called
      "true width".
      
      Signed-off-by: default avatarDaniel P. Berrangé <berrange@redhat.com>
      Reviewed-by: default avatarMarc-André Lureau <marcandre.lureau@redhat.com>
      Message-Id: <20210311182957.486939-5-berrange@redhat.com>
      Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
      69cc8db4
  6. Jan 15, 2021
    • Gerd Hoffmann's avatar
      vnc: add support for extended desktop resize · 763deea7
      Gerd Hoffmann authored
      The extended desktop resize encoding adds support for (a) clients
      sending resize requests to the server, and (b) multihead support.
      
      This patch implements (a).  All resize requests are rejected by qemu.
      Qemu can't resize the framebuffer on its own, this is in the hands of
      the guest, so all qemu can do is forward the request to the guest.
      Should the guest actually resize the framebuffer we can notify the vnc
      client later with a separate message.
      
      This requires support in the display device.  Works with virtio-gpu.
      
      https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst#extendeddesktopsize-pseudo-encoding
      
      
      
      Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
      Reviewed-by: default avatarDaniel P. Berrangé <berrange@redhat.com>
      Message-id: 20210112134120.2031837-4-kraxel@redhat.com
      763deea7
    • Daniel P. Berrangé's avatar
      ui: add support for remote power control to VNC server · 7b5fa0b5
      Daniel P. Berrangé authored
      
      The "XVP" (Xen VNC Proxy) extension defines a mechanism for a VNC client
      to issue power control requests to trigger graceful shutdown, reboot, or
      hard reset.
      
      This option is not enabled by default, since we cannot assume that users
      with VNC access implicitly have administrator access to the guest OS.
      
      Thus is it enabled with a boolean "power-control" option e.g.
      
         -vnc :1,power-control=on
      
      While, QEMU can easily support shutdown and reset, there's no easy way
      to wire up reboot support at this time. In theory it could be done by
      issuing a shutdown, followed by a reset, but there's no convenient
      wiring for such a pairing in QEMU. It also isn't possible to have the
      VNC server directly talk to QEMU guest agent, since the agent chardev is
      typically owned by an external mgmt app.
      
      Signed-off-by: default avatarDaniel P. Berrangé <berrange@redhat.com>
      
      [ kraxel: rebase to master  ]
      [ kraxel: add missing break ]
      
      Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
      7b5fa0b5
  7. Dec 11, 2020
  8. Dec 18, 2019
  9. Sep 17, 2019
    • Li Qiang's avatar
      vnc: fix memory leak when vnc disconnect · 6bf21f3d
      Li Qiang authored
      
      Currently when qemu receives a vnc connect, it creates a 'VncState' to
      represent this connection. In 'vnc_worker_thread_loop' it creates a
      local 'VncState'. The connection 'VcnState' and local 'VncState' exchange
      data in 'vnc_async_encoding_start' and 'vnc_async_encoding_end'.
      In 'zrle_compress_data' it calls 'deflateInit2' to allocate the libz library
      opaque data. The 'VncState' used in 'zrle_compress_data' is the local
      'VncState'. In 'vnc_zrle_clear' it calls 'deflateEnd' to free the libz
      library opaque data. The 'VncState' used in 'vnc_zrle_clear' is the connection
      'VncState'. In currently implementation there will be a memory leak when the
      vnc disconnect. Following is the asan output backtrack:
      
      Direct leak of 29760 byte(s) in 5 object(s) allocated from:
          0 0xffffa67ef3c3 in __interceptor_calloc (/lib64/libasan.so.4+0xd33c3)
          1 0xffffa65071cb in g_malloc0 (/lib64/libglib-2.0.so.0+0x571cb)
          2 0xffffa5e968f7 in deflateInit2_ (/lib64/libz.so.1+0x78f7)
          3 0xaaaacec58613 in zrle_compress_data ui/vnc-enc-zrle.c:87
          4 0xaaaacec58613 in zrle_send_framebuffer_update ui/vnc-enc-zrle.c:344
          5 0xaaaacec34e77 in vnc_send_framebuffer_update ui/vnc.c:919
          6 0xaaaacec5e023 in vnc_worker_thread_loop ui/vnc-jobs.c:271
          7 0xaaaacec5e5e7 in vnc_worker_thread ui/vnc-jobs.c:340
          8 0xaaaacee4d3c3 in qemu_thread_start util/qemu-thread-posix.c:502
          9 0xffffa544e8bb in start_thread (/lib64/libpthread.so.0+0x78bb)
          10 0xffffa53965cb in thread_start (/lib64/libc.so.6+0xd55cb)
      
      This is because the opaque allocated in 'deflateInit2' is not freed in
      'deflateEnd'. The reason is that the 'deflateEnd' calls 'deflateStateCheck'
      and in the latter will check whether 's->strm != strm'(libz's data structure).
      This check will be true so in 'deflateEnd' it just return 'Z_STREAM_ERROR' and
      not free the data allocated in 'deflateInit2'.
      
      The reason this happens is that the 'VncState' contains the whole 'VncZrle',
      so when calling 'deflateInit2', the 's->strm' will be the local address.
      So 's->strm != strm' will be true.
      
      To fix this issue, we need to make 'zrle' of 'VncState' to be a pointer.
      Then the connection 'VncState' and local 'VncState' exchange mechanism will
      work as expection. The 'tight' of 'VncState' has the same issue, let's also turn
      it to a pointer.
      
      Reported-by: default avatarYing Fang <fangying1@huawei.com>
      Signed-off-by: default avatarLi Qiang <liq3ea@163.com>
      Message-id: 20190831153922.121308-1-liq3ea@163.com
      Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
      6bf21f3d
  10. Aug 21, 2019
  11. Aug 16, 2019
    • Markus Armbruster's avatar
      Include generated QAPI headers less · 2ae16a6a
      Markus Armbruster authored
      
      Some of the generated qapi-types-MODULE.h are included all over the
      place.  Changing a QAPI type can trigger massive recompiling.  Top
      scorers recompile more than 1000 out of some 6600 objects (not
      counting tests and objects that don't depend on qemu/osdep.h):
      
          6300 qapi/qapi-builtin-types.h
          5700 qapi/qapi-types-run-state.h
          3900 qapi/qapi-types-common.h
          3300 qapi/qapi-types-sockets.h
          3000 qapi/qapi-types-misc.h
          3000 qapi/qapi-types-crypto.h
          3000 qapi/qapi-types-job.h
          3000 qapi/qapi-types-block-core.h
          2800 qapi/qapi-types-block.h
          1300 qapi/qapi-types-net.h
      
      Clean up headers to include generated QAPI headers only where needed.
      Impact is negligible except for hw/qdev-properties.h.
      
      This header includes qapi/qapi-types-block.h and
      qapi/qapi-types-misc.h.  They are used only in expansions of property
      definition macros such as DEFINE_PROP_BLOCKDEV_ON_ERROR() and
      DEFINE_PROP_OFF_AUTO().  Moving their inclusion from
      hw/qdev-properties.h to the users of these macros avoids pointless
      recompiles.  This is how other property definition macros, such as
      DEFINE_PROP_NETDEV(), already work.
      
      Improves things for some of the top scorers:
      
          3600 qapi/qapi-types-common.h
          2800 qapi/qapi-types-sockets.h
           900 qapi/qapi-types-misc.h
          2200 qapi/qapi-types-crypto.h
          2100 qapi/qapi-types-job.h
          2100 qapi/qapi-types-block-core.h
           270 qapi/qapi-types-block.h
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Reviewed-by: default avatarEric Blake <eblake@redhat.com>
      Reviewed-by: default avatarPhilippe Mathieu-Daudé <philmd@redhat.com>
      Tested-by: default avatarPhilippe Mathieu-Daudé <philmd@redhat.com>
      Message-Id: <20190812052359.30071-3-armbru@redhat.com>
      2ae16a6a
  12. Jun 12, 2019
    • Markus Armbruster's avatar
      Include qemu-common.h exactly where needed · a8d25326
      Markus Armbruster authored
      
      No header includes qemu-common.h after this commit, as prescribed by
      qemu-common.h's file comment.
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Message-Id: <20190523143508.25387-5-armbru@redhat.com>
      [Rebased with conflicts resolved automatically, except for
      include/hw/arm/xlnx-zynqmp.h hw/arm/nrf51_soc.c hw/arm/msf2-soc.c
      block/qcow2-refcount.c block/qcow2-cluster.c block/qcow2-cache.c
      target/arm/cpu.h target/lm32/cpu.h target/m68k/cpu.h target/mips/cpu.h
      target/moxie/cpu.h target/nios2/cpu.h target/openrisc/cpu.h
      target/riscv/cpu.h target/tilegx/cpu.h target/tricore/cpu.h
      target/unicore32/cpu.h target/xtensa/cpu.h; bsd-user/main.c and
      net/tap-bsd.c fixed up]
      a8d25326
  13. Feb 26, 2019
  14. Feb 05, 2019
  15. Jul 03, 2018
    • Marc-André Lureau's avatar
      qapi: add conditions to VNC type/commands/events on the schema · 05eb4a25
      Marc-André Lureau authored
      
      Add #if defined(CONFIG_VNC) in generated code, and adjust the
      qmp/hmp code accordingly.
      
      query-qmp-schema no longer reports the command/events etc as
      available when disabled at compile.
      
      Commands made conditional:
      
      * query-vnc, query-vnc-servers, change-vnc-password
      
        Before the patch, the commands for !CONFIG_VNC are stubs that fail
        like this:
      
          {"error": {"class": "GenericError",
                     "desc": "The feature 'vnc' is not enabled"}}
      
        Afterwards, they fail like this:
      
          {"error": {"class": "CommandNotFound",
                     "desc": "The command FOO has not been found"}}
      
        I call that an improvement, because it lets clients distinguish
        between command unavailable (class CommandNotFound) and command failed
        (class GenericError).
      
      Events made conditional:
      
      * VNC_CONNECTED, VNC_INITIALIZED, VNC_DISCONNECTED
      
      HMP change:
      
      * info vnc
      
        Will return "unknown command: 'info vnc'" when VNC is compiled
        out (same as error for spice when --disable-spice)
      
      Occurrences of VNC (case insensitive) in the schema that aren't
      covered by this change:
      
      * add_client
      
        Command has other uses, including "socket bases character devices".
        These are unconditional as far as I can tell.
      
      * set_password, expire_password
      
        In theory, these commands could be used for managing any service's
        password.  In practice, they're used for VNC and SPICE services.
        They're documented for "remote display session" / "remote display
        server".
      
        The service is selected by argument @protocol.  The code special-cases
        protocol-specific argument checking, then calls a protocol-specific
        function to do the work.  If it fails, the command fails with "Could
        not set password".  It does when the service isn't compiled in (it's a
        stub then).
      
        We could make these commands conditional on the conjunction of all
        services [currently: defined(CONFIG_VNC) || defined(CONFIG_SPICE)],
        but I doubt it's worthwhile.
      
      * change
      
        Command has other uses, namely changing media.
        This patch inlines a stub; no functional change.
      
      Signed-off-by: default avatarMarc-André Lureau <marcandre.lureau@redhat.com>
      Reviewed-by: default avatarGerd Hoffmann <kraxel@redhat.com>
      Reviewed-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Message-Id: <20180703155648.11933-14-marcandre.lureau@redhat.com>
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      05eb4a25
  16. May 15, 2018
  17. Mar 02, 2018
  18. Feb 09, 2018
  19. Feb 02, 2018
  20. Jan 25, 2018
    • Daniel P. Berrangé's avatar
      ui: avoid sign extension using client width/height · 4c956bd8
      Daniel P. Berrangé authored
      
      Pixman returns a signed int for the image width/height, but the VNC
      protocol only permits a unsigned int16. Effective framebuffer size
      is determined by the guest, limited by the video RAM size, so the
      dimensions are unlikely to exceed the range of an unsigned int16,
      but this is not currently validated.
      
      With the current use of 'int' for client width/height, the calculation
      of offsets in vnc_update_throttle_offset() suffers from integer size
      promotion and sign extension, causing coverity warnings
      
      *** CID 1385147:  Integer handling issues  (SIGN_EXTENSION)
      /ui/vnc.c: 979 in vnc_update_throttle_offset()
      973      * than that the client would already suffering awful audio
      974      * glitches, so dropping samples is no worse really).
      975      */
      976     static void vnc_update_throttle_offset(VncState *vs)
      977     {
      978         size_t offset =
      >>>     CID 1385147:  Integer handling issues  (SIGN_EXTENSION)
      >>>     Suspicious implicit sign extension:
          "vs->client_pf.bytes_per_pixel" with type "unsigned char" (8 bits,
          unsigned) is promoted in "vs->client_width * vs->client_height *
          vs->client_pf.bytes_per_pixel" to type "int" (32 bits, signed), then
          sign-extended to type "unsigned long" (64 bits, unsigned).  If
          "vs->client_width * vs->client_height * vs->client_pf.bytes_per_pixel"
          is greater than 0x7FFFFFFF, the upper bits of the result will all be 1.
      979             vs->client_width * vs->client_height * vs->client_pf.bytes_per_pixel;
      
      Change client_width / client_height to be a size_t to avoid sign
      extension and integer promotion. Then validate that dimensions are in
      range wrt the RFB protocol u16 limits.
      
      Signed-off-by: default avatarDaniel P. Berrange <berrange@redhat.com>
      Message-id: 20180118155254.17053-1-berrange@redhat.com
      Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
      4c956bd8
  21. Jan 12, 2018
    • Daniel P. Berrangé's avatar
      ui: mix misleading comments & return types of VNC I/O helper methods · 30b80fd5
      Daniel P. Berrangé authored
      
      While the QIOChannel APIs for reading/writing data return ssize_t, with negative
      value indicating an error, the VNC code passes this return value through the
      vnc_client_io_error() method. This detects the error condition, disconnects the
      client and returns 0 to indicate error. Thus all the VNC helper methods should
      return size_t (unsigned), and misleading comments which refer to the possibility
      of negative return values need fixing.
      
      Signed-off-by: default avatarDaniel P. Berrange <berrange@redhat.com>
      Reviewed-by: default avatarDarren Kenny <darren.kenny@oracle.com>
      Reviewed-by: default avatarMarc-André Lureau <marcandre.lureau@redhat.com>
      Message-id: 20171218191228.31018-14-berrange@redhat.com
      Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
      30b80fd5
    • Daniel P. Berrangé's avatar
      ui: fix VNC client throttling when forced update is requested · ada8d2e4
      Daniel P. Berrangé authored
      
      The VNC server must throttle data sent to the client to prevent the 'output'
      buffer size growing without bound, if the client stops reading data off the
      socket (either maliciously or due to stalled/slow network connection).
      
      The current throttling is very crude because it simply checks whether the
      output buffer offset is zero. This check is disabled if the client has requested
      a forced update, because we want to send these as soon as possible.
      
      As a result, the VNC client can cause QEMU to allocate arbitrary amounts of RAM.
      They can first start something in the guest that triggers lots of framebuffer
      updates eg play a youtube video. Then repeatedly send full framebuffer update
      requests, but never read data back from the server. This can easily make QEMU's
      VNC server send buffer consume 100MB of RAM per second, until the OOM killer
      starts reaping processes (hopefully the rogue QEMU process, but it might pick
      others...).
      
      To address this we make the throttling more intelligent, so we can throttle
      full updates. When we get a forced update request, we keep track of exactly how
      much data we put on the output buffer. We will not process a subsequent forced
      update request until this data has been fully sent on the wire. We always allow
      one forced update request to be in flight, regardless of what data is queued
      for incremental updates or audio data. The slight complication is that we do
      not initially know how much data an update will send, as this is done in the
      background by the VNC job thread. So we must track the fact that the job thread
      has an update pending, and not process any further updates until this job is
      has been completed & put data on the output buffer.
      
      This unbounded memory growth affects all VNC server configurations supported by
      QEMU, with no workaround possible. The mitigating factor is that it can only be
      triggered by a client that has authenticated with the VNC server, and who is
      able to trigger a large quantity of framebuffer updates or audio samples from
      the guest OS. Mostly they'll just succeed in getting the OOM killer to kill
      their own QEMU process, but its possible other processes can get taken out as
      collateral damage.
      
      This is a more general variant of the similar unbounded memory usage flaw in
      the websockets server, that was previously assigned CVE-2017-15268, and fixed
      in 2.11 by:
      
        commit a7b20a8e
        Author: Daniel P. Berrange <berrange@redhat.com>
        Date:   Mon Oct 9 14:43:42 2017 +0100
      
          io: monitor encoutput buffer size from websocket GSource
      
      This new general memory usage flaw has been assigned CVE-2017-15124, and is
      partially fixed by this patch.
      
      Signed-off-by: default avatarDaniel P. Berrange <berrange@redhat.com>
      Reviewed-by: default avatarDarren Kenny <darren.kenny@oracle.com>
      Reviewed-by: default avatarMarc-André Lureau <marcandre.lureau@redhat.com>
      Message-id: 20171218191228.31018-11-berrange@redhat.com
      Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
      ada8d2e4
    • Daniel P. Berrangé's avatar
      ui: fix VNC client throttling when audio capture is active · e2b72cb6
      Daniel P. Berrangé authored
      
      The VNC server must throttle data sent to the client to prevent the 'output'
      buffer size growing without bound, if the client stops reading data off the
      socket (either maliciously or due to stalled/slow network connection).
      
      The current throttling is very crude because it simply checks whether the
      output buffer offset is zero. This check must be disabled if audio capture is
      enabled, because when streaming audio the output buffer offset will rarely be
      zero due to queued audio data, and so this would starve framebuffer updates.
      
      As a result, the VNC client can cause QEMU to allocate arbitrary amounts of RAM.
      They can first start something in the guest that triggers lots of framebuffer
      updates eg play a youtube video. Then enable audio capture, and simply never
      read data back from the server. This can easily make QEMU's VNC server send
      buffer consume 100MB of RAM per second, until the OOM killer starts reaping
      processes (hopefully the rogue QEMU process, but it might pick others...).
      
      To address this we make the throttling more intelligent, so we can throttle
      when audio capture is active too. To determine how to throttle incremental
      updates or audio data, we calculate a size threshold. Normally the threshold is
      the approximate number of bytes associated with a single complete framebuffer
      update. ie width * height * bytes per pixel. We'll send incremental updates
      until we hit this threshold, at which point we'll stop sending updates until
      data has been written to the wire, causing the output buffer offset to fall
      back below the threshold.
      
      If audio capture is enabled, we increase the size of the threshold to also
      allow for upto 1 seconds worth of audio data samples. ie nchannels * bytes
      per sample * frequency. This allows the output buffer to have a mixture of
      incremental framebuffer updates and audio data queued, but once the threshold
      is exceeded, audio data will be dropped and incremental updates will be
      throttled.
      
      This unbounded memory growth affects all VNC server configurations supported by
      QEMU, with no workaround possible. The mitigating factor is that it can only be
      triggered by a client that has authenticated with the VNC server, and who is
      able to trigger a large quantity of framebuffer updates or audio samples from
      the guest OS. Mostly they'll just succeed in getting the OOM killer to kill
      their own QEMU process, but its possible other processes can get taken out as
      collateral damage.
      
      This is a more general variant of the similar unbounded memory usage flaw in
      the websockets server, that was previously assigned CVE-2017-15268, and fixed
      in 2.11 by:
      
        commit a7b20a8e
        Author: Daniel P. Berrange <berrange@redhat.com>
        Date:   Mon Oct 9 14:43:42 2017 +0100
      
          io: monitor encoutput buffer size from websocket GSource
      
      This new general memory usage flaw has been assigned CVE-2017-15124, and is
      partially fixed by this patch.
      
      Signed-off-by: default avatarDaniel P. Berrange <berrange@redhat.com>
      Reviewed-by: default avatarDarren Kenny <darren.kenny@oracle.com>
      Reviewed-by: default avatarMarc-André Lureau <marcandre.lureau@redhat.com>
      Message-id: 20171218191228.31018-10-berrange@redhat.com
      Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
      e2b72cb6
    • Daniel P. Berrangé's avatar
      ui: introduce enum to track VNC client framebuffer update request state · fef1bbad
      Daniel P. Berrangé authored
      
      Currently the VNC servers tracks whether a client has requested an incremental
      or forced update with two boolean flags. There are only really 3 distinct
      states to track, so create an enum to more accurately reflect permitted states.
      
      Signed-off-by: default avatarDaniel P. Berrange <berrange@redhat.com>
      Reviewed-by: default avatarDarren Kenny <darren.kenny@oracle.com>
      Reviewed-by: default avatarMarc-André Lureau <marcandre.lureau@redhat.com>
      Message-id: 20171218191228.31018-7-berrange@redhat.com
      Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
      fef1bbad
  22. Feb 08, 2017
    • Daniel P. Berrangé's avatar
      ui: refactor VncDisplay to allow multiple listening sockets · 4ee74fa7
      Daniel P. Berrangé authored
      
      Currently there is only a single listener for plain VNC and
      a single listener for websockets VNC. This means that if
      getaddrinfo() returns multiple IP addresses, for a hostname,
      the VNC server can only listen on one of them. This is
      just bearable if listening on wildcard interface, or if
      the host only has a single network interface to listen on,
      but if there are multiple NICs and the VNC server needs
      to listen on 2 or more specific IP addresses, it can't be
      done.
      
      This refactors the VncDisplay state so that it holds an
      array of listening sockets, but still only listens on
      one socket.
      
      Reviewed-by: default avatarEric Blake <eblake@redhat.com>
      Signed-off-by: default avatarDaniel P. Berrange <berrange@redhat.com>
      Message-id: 20170203120649.15637-4-berrange@redhat.com
      Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
      4ee74fa7
  23. Jan 31, 2017
  24. Oct 13, 2016
  25. Jul 12, 2016
  26. Jun 03, 2016
  27. Feb 23, 2016
  28. Dec 18, 2015
Loading