|
|
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 |
|