qemu-commits
[Top][All Lists]
Advanced

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

[Qemu-commits] [qemu/qemu] 090fdc: vnc: fix debug spelling


From: GitHub
Subject: [Qemu-commits] [qemu/qemu] 090fdc: vnc: fix debug spelling
Date: Fri, 12 Jan 2018 08:39:07 -0800

  Branch: refs/heads/master
  Home:   https://github.com/qemu/qemu
  Commit: 090fdc83b0960f68d204624a73c6814780da52d9
      
https://github.com/qemu/qemu/commit/090fdc83b0960f68d204624a73c6814780da52d9
  Author: Marc-André Lureau <address@hidden>
  Date:   2018-01-12 (Fri, 12 Jan 2018)

  Changed paths:
    M ui/vnc.c

  Log Message:
  -----------
  vnc: fix debug spelling

Signed-off-by: Marc-André Lureau <address@hidden>
Message-id: address@hidden
Signed-off-by: Gerd Hoffmann <address@hidden>


  Commit: 6af998db05aec9af95a06f84ad94f1b96785e667
      
https://github.com/qemu/qemu/commit/6af998db05aec9af95a06f84ad94f1b96785e667
  Author: Daniel P. Berrange <address@hidden>
  Date:   2018-01-12 (Fri, 12 Jan 2018)

  Changed paths:
    M ui/vnc.c

  Log Message:
  -----------
  ui: remove 'sync' parameter from vnc_update_client

There is only one caller of vnc_update_client and that always passes false
for the 'sync' parameter.

Signed-off-by: Daniel P. Berrange <address@hidden>
Reviewed-by: Darren Kenny <address@hidden>
Reviewed-by: Marc-André Lureau <address@hidden>
Message-id: address@hidden
Signed-off-by: Gerd Hoffmann <address@hidden>


  Commit: c53df961617736f94731d94b62c2954c261d2bae
      
https://github.com/qemu/qemu/commit/c53df961617736f94731d94b62c2954c261d2bae
  Author: Daniel P. Berrange <address@hidden>
  Date:   2018-01-12 (Fri, 12 Jan 2018)

  Changed paths:
    M ui/vnc.c

  Log Message:
  -----------
  ui: remove unreachable code in vnc_update_client

A previous commit:

  commit 5a8be0f73d6f60ff08746377eb09ca459f39deab
  Author: Gerd Hoffmann <address@hidden>
  Date:   Wed Jul 13 12:21:20 2016 +0200

    vnc: make sure we finish disconnect

Added a check for vs->disconnecting at the very start of the
vnc_update_client method. This means that the very next "if"
statement check for !vs->disconnecting always evaluates true,
and is thus redundant. This in turn means the vs->disconnecting
check at the very end of the method never evaluates true, and
is thus unreachable code.

Signed-off-by: Daniel P. Berrange <address@hidden>
Reviewed-by: Darren Kenny <address@hidden>
Reviewed-by: Marc-André Lureau <address@hidden>
Message-id: address@hidden
Signed-off-by: Gerd Hoffmann <address@hidden>


  Commit: b939eb89b6f320544a9328fa908d881d0024c1ee
      
https://github.com/qemu/qemu/commit/b939eb89b6f320544a9328fa908d881d0024c1ee
  Author: Daniel P. Berrange <address@hidden>
  Date:   2018-01-12 (Fri, 12 Jan 2018)

  Changed paths:
    M ui/vnc.c

  Log Message:
  -----------
  ui: remove redundant indentation in vnc_client_update

Now that previous dead / unreachable code has been removed, we can simplify
the indentation in the vnc_client_update method.

Signed-off-by: Daniel P. Berrange <address@hidden>
Reviewed-by: Darren Kenny <address@hidden>
Reviewed-by: Marc-André Lureau <address@hidden>
Message-id: address@hidden
Signed-off-by: Gerd Hoffmann <address@hidden>


  Commit: 3541b08475d51bddf8aded36576a0ff5a547a978
      
https://github.com/qemu/qemu/commit/3541b08475d51bddf8aded36576a0ff5a547a978
  Author: Daniel P. Berrange <address@hidden>
  Date:   2018-01-12 (Fri, 12 Jan 2018)

  Changed paths:
    M ui/vnc.c

  Log Message:
  -----------
  ui: avoid pointless VNC updates if framebuffer isn't dirty

The vnc_update_client() method checks the 'has_dirty' flag to see if there are
dirty regions that are pending to send to the client. Regardless of this flag,
if a forced update is requested, updates must be sent. For unknown reasons
though, the code also tries to sent updates if audio capture is enabled. This
makes no sense as audio capture state does not impact framebuffer contents, so
this check is removed.

Signed-off-by: Daniel P. Berrange <address@hidden>
Reviewed-by: Darren Kenny <address@hidden>
Reviewed-by: Marc-André Lureau <address@hidden>
Message-id: address@hidden
Signed-off-by: Gerd Hoffmann <address@hidden>


  Commit: 8f61f1c5a6bc06438a1172efa80bc7606594fa07
      
https://github.com/qemu/qemu/commit/8f61f1c5a6bc06438a1172efa80bc7606594fa07
  Author: Daniel P. Berrange <address@hidden>
  Date:   2018-01-12 (Fri, 12 Jan 2018)

  Changed paths:
    M ui/vnc-auth-sasl.c
    M ui/vnc-auth-sasl.h

  Log Message:
  -----------
  ui: track how much decoded data we consumed when doing SASL encoding

When we encode data for writing with SASL, we encode the entire pending output
buffer. The subsequent write, however, may not be able to send the full encoded
data in one go though, particularly with a slow network. So we delay setting the
output buffer offset back to zero until all the SASL encoded data is sent.

Between encoding the data and completing sending of the SASL encoded data,
however, more data might have been placed on the pending output buffer. So it
is not valid to set offset back to zero. Instead we must keep track of how much
data we consumed during encoding and subtract only that amount.

With the current bug we would be throwing away some pending data without having
sent it at all. By sheer luck this did not previously cause any serious problem
because appending data to the send buffer is always an atomic action, so we
only ever throw away complete RFB protocol messages. In the case of frame buffer
updates we'd catch up fairly quickly, so no obvious problem was visible.

Signed-off-by: Daniel P. Berrange <address@hidden>
Reviewed-by: Darren Kenny <address@hidden>
Reviewed-by: Marc-André Lureau <address@hidden>
Message-id: address@hidden
Signed-off-by: Gerd Hoffmann <address@hidden>


  Commit: fef1bbadfb2c3027208eb3d14b43e1bdb51166ca
      
https://github.com/qemu/qemu/commit/fef1bbadfb2c3027208eb3d14b43e1bdb51166ca
  Author: Daniel P. Berrange <address@hidden>
  Date:   2018-01-12 (Fri, 12 Jan 2018)

  Changed paths:
    M ui/vnc.c
    M ui/vnc.h

  Log Message:
  -----------
  ui: introduce enum to track VNC client framebuffer update request state

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: Daniel P. Berrange <address@hidden>
Reviewed-by: Darren Kenny <address@hidden>
Reviewed-by: Marc-André Lureau <address@hidden>
Message-id: address@hidden
Signed-off-by: Gerd Hoffmann <address@hidden>


  Commit: 728a7ac95484a7ba5e624ccbac4c1326571576b0
      
https://github.com/qemu/qemu/commit/728a7ac95484a7ba5e624ccbac4c1326571576b0
  Author: Daniel P. Berrange <address@hidden>
  Date:   2018-01-12 (Fri, 12 Jan 2018)

  Changed paths:
    M ui/vnc.c

  Log Message:
  -----------
  ui: correctly reset framebuffer update state after processing dirty regions

According to the RFB protocol, a client sends one or more framebuffer update
requests to the server. The server can reply with a single framebuffer update
response, that covers all previously received requests. Once the client has
read this update from the server, it may send further framebuffer update
requests to monitor future changes. The client is free to delay sending the
framebuffer update request if it needs to throttle the amount of data it is
reading from the server.

The QEMU VNC server, however, has never correctly handled the framebuffer
update requests. Once QEMU has received an update request, it will continue to
send client updates forever, even if the client hasn't asked for further
updates. This prevents the client from throttling back data it gets from the
server. This change fixes the flawed logic such that after a set of updates are
sent out, QEMU waits for a further update request before sending more data.

Signed-off-by: Daniel P. Berrange <address@hidden>
Reviewed-by: Darren Kenny <address@hidden>
Reviewed-by: Marc-André Lureau <address@hidden>
Message-id: address@hidden
Signed-off-by: Gerd Hoffmann <address@hidden>


  Commit: 0bad834228b9ee63e4239108d02dcb94568254d0
      
https://github.com/qemu/qemu/commit/0bad834228b9ee63e4239108d02dcb94568254d0
  Author: Daniel P. Berrange <address@hidden>
  Date:   2018-01-12 (Fri, 12 Jan 2018)

  Changed paths:
    M ui/vnc.c

  Log Message:
  -----------
  ui: refactor code for determining if an update should be sent to the client

The logic for determining if it is possible to send an update to the client
will become more complicated shortly, so pull it out into a separate method
for easier extension later.

Signed-off-by: Daniel P. Berrange <address@hidden>
Reviewed-by: Darren Kenny <address@hidden>
Reviewed-by: Marc-André Lureau <address@hidden>
Message-id: address@hidden
Signed-off-by: Gerd Hoffmann <address@hidden>


  Commit: e2b72cb6e0443d90d7ab037858cb6834b6cca852
      
https://github.com/qemu/qemu/commit/e2b72cb6e0443d90d7ab037858cb6834b6cca852
  Author: Daniel P. Berrange <address@hidden>
  Date:   2018-01-12 (Fri, 12 Jan 2018)

  Changed paths:
    M ui/vnc.c
    M ui/vnc.h

  Log Message:
  -----------
  ui: fix VNC client throttling when audio capture is active

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 a7b20a8efa28e5f22c26c06cd06c2f12bc863493
  Author: Daniel P. Berrange <address@hidden>
  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: Daniel P. Berrange <address@hidden>
Reviewed-by: Darren Kenny <address@hidden>
Reviewed-by: Marc-André Lureau <address@hidden>
Message-id: address@hidden
Signed-off-by: Gerd Hoffmann <address@hidden>


  Commit: ada8d2e4369ea49677d8672ac81bce73eefd5b54
      
https://github.com/qemu/qemu/commit/ada8d2e4369ea49677d8672ac81bce73eefd5b54
  Author: Daniel P. Berrange <address@hidden>
  Date:   2018-01-12 (Fri, 12 Jan 2018)

  Changed paths:
    M ui/vnc-auth-sasl.c
    M ui/vnc-jobs.c
    M ui/vnc.c
    M ui/vnc.h

  Log Message:
  -----------
  ui: fix VNC client throttling when forced update is requested

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 a7b20a8efa28e5f22c26c06cd06c2f12bc863493
  Author: Daniel P. Berrange <address@hidden>
  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: Daniel P. Berrange <address@hidden>
Reviewed-by: Darren Kenny <address@hidden>
Reviewed-by: Marc-André Lureau <address@hidden>
Message-id: address@hidden
Signed-off-by: Gerd Hoffmann <address@hidden>


  Commit: f887cf165db20f405cb8805c716bd363aaadf815
      
https://github.com/qemu/qemu/commit/f887cf165db20f405cb8805c716bd363aaadf815
  Author: Daniel P. Berrange <address@hidden>
  Date:   2018-01-12 (Fri, 12 Jan 2018)

  Changed paths:
    M ui/vnc.c

  Log Message:
  -----------
  ui: place a hard cap on VNC server output buffer size

The previous patches fix problems with throttling of forced framebuffer updates
and audio data capture that would cause the QEMU output buffer size to grow
without bound. Those fixes are graceful in that once the client catches up with
reading data from the server, everything continues operating normally.

There is some data which the server sends to the client that is impractical to
throttle. Specifically there are various pseudo framebuffer update encodings to
inform the client of things like desktop resizes, pointer changes, audio
playback start/stop, LED state and so on. These generally only involve sending
a very small amount of data to the client, but a malicious guest might be able
to do things that trigger these changes at a very high rate. Throttling them is
not practical as missed or delayed events would cause broken behaviour for the
client.

This patch thus takes a more forceful approach of setting an absolute upper
bound on the amount of data we permit to be present in the output buffer at
any time. The previous patch set a threshold for throttling the output buffer
by allowing an amount of data equivalent to one complete framebuffer update and
one seconds worth of audio data. On top of this it allowed for one further
forced framebuffer update to be queued.

To be conservative, we thus take that throttling threshold and multiply it by
5 to form an absolute upper bound. If this bound is hit during vnc_write() we
forceably disconnect the client, refusing to queue further data. This limit is
high enough that it should never be hit unless a malicious client is trying to
exploit the sever, or the network is completely saturated preventing any sending
of data on the socket.

This completes the fix for CVE-2017-15124 started in the previous patches.

Signed-off-by: Daniel P. Berrange <address@hidden>
Reviewed-by: Darren Kenny <address@hidden>
Reviewed-by: Marc-André Lureau <address@hidden>
Message-id: address@hidden
Signed-off-by: Gerd Hoffmann <address@hidden>


  Commit: 6aa22a29187e1908f5db738d27c64a9efc8d0bfa
      
https://github.com/qemu/qemu/commit/6aa22a29187e1908f5db738d27c64a9efc8d0bfa
  Author: Daniel P. Berrange <address@hidden>
  Date:   2018-01-12 (Fri, 12 Jan 2018)

  Changed paths:
    M ui/trace-events
    M ui/vnc.c

  Log Message:
  -----------
  ui: add trace events related to VNC client throttling

The VNC client throttling is quite subtle so will benefit from having trace
points available for live debugging.

Signed-off-by: Daniel P. Berrange <address@hidden>
Reviewed-by: Darren Kenny <address@hidden>
Reviewed-by: Marc-André Lureau <address@hidden>
Message-id: address@hidden
Signed-off-by: Gerd Hoffmann <address@hidden>


  Commit: 30b80fd5269257f55203b7072c505b4ebaab5115
      
https://github.com/qemu/qemu/commit/30b80fd5269257f55203b7072c505b4ebaab5115
  Author: Daniel P. Berrange <address@hidden>
  Date:   2018-01-12 (Fri, 12 Jan 2018)

  Changed paths:
    M ui/vnc-auth-sasl.c
    M ui/vnc-auth-sasl.h
    M ui/vnc.c
    M ui/vnc.h

  Log Message:
  -----------
  ui: mix misleading comments & return types of VNC I/O helper methods

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: Daniel P. Berrange <address@hidden>
Reviewed-by: Darren Kenny <address@hidden>
Reviewed-by: Marc-André Lureau <address@hidden>
Message-id: address@hidden
Signed-off-by: Gerd Hoffmann <address@hidden>


  Commit: 7398166ddf7c6dbbc9cae6ac69bb2feda14b40ac
      
https://github.com/qemu/qemu/commit/7398166ddf7c6dbbc9cae6ac69bb2feda14b40ac
  Author: Peter Maydell <address@hidden>
  Date:   2018-01-12 (Fri, 12 Jan 2018)

  Changed paths:
    M ui/trace-events
    M ui/vnc-auth-sasl.c
    M ui/vnc-auth-sasl.h
    M ui/vnc-jobs.c
    M ui/vnc.c
    M ui/vnc.h

  Log Message:
  -----------
  Merge remote-tracking branch 'remotes/kraxel/tags/vnc-20180112-pull-request' 
into staging

vnc: limit memory usage (CVE-2017-15124)

# gpg: Signature made Fri 12 Jan 2018 12:57:22 GMT
# gpg:                using RSA key 0x4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <address@hidden>"
# gpg:                 aka "Gerd Hoffmann <address@hidden>"
# gpg:                 aka "Gerd Hoffmann (private) <address@hidden>"
# Primary key fingerprint: A032 8CFF B93A 17A7 9901  FE7D 4CB6 D8EE D3E8 7138

* remotes/kraxel/tags/vnc-20180112-pull-request:
  ui: mix misleading comments & return types of VNC I/O helper methods
  ui: add trace events related to VNC client throttling
  ui: place a hard cap on VNC server output buffer size
  ui: fix VNC client throttling when forced update is requested
  ui: fix VNC client throttling when audio capture is active
  ui: refactor code for determining if an update should be sent to the client
  ui: correctly reset framebuffer update state after processing dirty regions
  ui: introduce enum to track VNC client framebuffer update request state
  ui: track how much decoded data we consumed when doing SASL encoding
  ui: avoid pointless VNC updates if framebuffer isn't dirty
  ui: remove redundant indentation in vnc_client_update
  ui: remove unreachable code in vnc_update_client
  ui: remove 'sync' parameter from vnc_update_client
  vnc: fix debug spelling

Signed-off-by: Peter Maydell <address@hidden>


Compare: https://github.com/qemu/qemu/compare/a3380cf658e1...7398166ddf7c

reply via email to

[Prev in Thread] Current Thread [Next in Thread]