Blame SOURCES/kvm-ui-avoid-sign-extension-using-client-width-height.patch

9bac43
From 31d7d5079364726d5a048d96e1e368173b83ab80 Mon Sep 17 00:00:00 2001
9bac43
From: "Daniel P. Berrange" <berrange@redhat.com>
9bac43
Date: Mon, 5 Feb 2018 11:10:11 +0100
9bac43
Subject: [PATCH 17/20] ui: avoid sign extension using client width/height
9bac43
9bac43
RH-Author: Daniel P. Berrange <berrange@redhat.com>
9bac43
Message-id: <20180205111012.6210-17-berrange@redhat.com>
9bac43
Patchwork-id: 78889
9bac43
O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 16/17] ui: avoid sign extension using client width/height
9bac43
Bugzilla: 1527404
9bac43
RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
9bac43
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
9bac43
RH-Acked-by: Thomas Huth <thuth@redhat.com>
9bac43
9bac43
From: "Daniel P. Berrange" <berrange@redhat.com>
9bac43
9bac43
Pixman returns a signed int for the image width/height, but the VNC
9bac43
protocol only permits a unsigned int16. Effective framebuffer size
9bac43
is determined by the guest, limited by the video RAM size, so the
9bac43
dimensions are unlikely to exceed the range of an unsigned int16,
9bac43
but this is not currently validated.
9bac43
9bac43
With the current use of 'int' for client width/height, the calculation
9bac43
of offsets in vnc_update_throttle_offset() suffers from integer size
9bac43
promotion and sign extension, causing coverity warnings
9bac43
9bac43
*** CID 1385147:  Integer handling issues  (SIGN_EXTENSION)
9bac43
/ui/vnc.c: 979 in vnc_update_throttle_offset()
9bac43
973      * than that the client would already suffering awful audio
9bac43
974      * glitches, so dropping samples is no worse really).
9bac43
975      */
9bac43
976     static void vnc_update_throttle_offset(VncState *vs)
9bac43
977     {
9bac43
978         size_t offset =
9bac43
>>>     CID 1385147:  Integer handling issues  (SIGN_EXTENSION)
9bac43
>>>     Suspicious implicit sign extension:
9bac43
    "vs->client_pf.bytes_per_pixel" with type "unsigned char" (8 bits,
9bac43
    unsigned) is promoted in "vs->client_width * vs->client_height *
9bac43
    vs->client_pf.bytes_per_pixel" to type "int" (32 bits, signed), then
9bac43
    sign-extended to type "unsigned long" (64 bits, unsigned).  If
9bac43
    "vs->client_width * vs->client_height * vs->client_pf.bytes_per_pixel"
9bac43
    is greater than 0x7FFFFFFF, the upper bits of the result will all be 1.
9bac43
979             vs->client_width * vs->client_height * vs->client_pf.bytes_per_pixel;
9bac43
9bac43
Change client_width / client_height to be a size_t to avoid sign
9bac43
extension and integer promotion. Then validate that dimensions are in
9bac43
range wrt the RFB protocol u16 limits.
9bac43
9bac43
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
9bac43
Message-id: 20180118155254.17053-1-berrange@redhat.com
9bac43
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
9bac43
(cherry picked from commit 4c956bd81e2e16afd19d38d1fdeba6d9faa8a1ae)
9bac43
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9bac43
---
9bac43
 ui/vnc.c | 9 +++++++++
9bac43
 ui/vnc.h | 4 ++--
9bac43
 2 files changed, 11 insertions(+), 2 deletions(-)
9bac43
9bac43
diff --git a/ui/vnc.c b/ui/vnc.c
9bac43
index b303930..fec4f4c 100644
9bac43
--- a/ui/vnc.c
9bac43
+++ b/ui/vnc.c
9bac43
@@ -672,6 +672,11 @@ static void vnc_desktop_resize(VncState *vs)
9bac43
         vs->client_height == pixman_image_get_height(vs->vd->server)) {
9bac43
         return;
9bac43
     }
9bac43
+
9bac43
+    assert(pixman_image_get_width(vs->vd->server) < 65536 &&
9bac43
+           pixman_image_get_width(vs->vd->server) >= 0);
9bac43
+    assert(pixman_image_get_height(vs->vd->server) < 65536 &&
9bac43
+           pixman_image_get_height(vs->vd->server) >= 0);
9bac43
     vs->client_width = pixman_image_get_width(vs->vd->server);
9bac43
     vs->client_height = pixman_image_get_height(vs->vd->server);
9bac43
     vnc_lock_output(vs);
9bac43
@@ -2490,6 +2495,10 @@ static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
9bac43
         return 0;
9bac43
     }
9bac43
 
9bac43
+    assert(pixman_image_get_width(vs->vd->server) < 65536 &&
9bac43
+           pixman_image_get_width(vs->vd->server) >= 0);
9bac43
+    assert(pixman_image_get_height(vs->vd->server) < 65536 &&
9bac43
+           pixman_image_get_height(vs->vd->server) >= 0);
9bac43
     vs->client_width = pixman_image_get_width(vs->vd->server);
9bac43
     vs->client_height = pixman_image_get_height(vs->vd->server);
9bac43
     vnc_write_u16(vs, vs->client_width);
9bac43
diff --git a/ui/vnc.h b/ui/vnc.h
9bac43
index 0c33a5f..bbda054 100644
9bac43
--- a/ui/vnc.h
9bac43
+++ b/ui/vnc.h
9bac43
@@ -278,8 +278,8 @@ struct VncState
9bac43
     int last_x;
9bac43
     int last_y;
9bac43
     uint32_t last_bmask;
9bac43
-    int client_width;
9bac43
-    int client_height;
9bac43
+    size_t client_width; /* limited to u16 by RFB proto */
9bac43
+    size_t client_height; /* limited to u16 by RFB proto */
9bac43
     VncShareMode share_mode;
9bac43
 
9bac43
     uint32_t vnc_encoding;
9bac43
-- 
9bac43
1.8.3.1
9bac43