1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
From 9308d0c6365861fbd2eafa0a0881acef460cfc15 Mon Sep 17 00:00:00 2001
From: Armin Novak <armin.novak@thincast.com>
Date: Fri, 12 Mar 2021 09:12:28 +0100
Subject: [PATCH 24/36] Added bounds checks to gfx commands
(cherry picked from commit dd61853142a07af0eca80c901292075373a6b2d6)
libfreerdp/gdi/gfx.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/libfreerdp/gdi/gfx.c b/libfreerdp/gdi/gfx.c
index 238c8138d..2221cc3f7 100644
@@ -42,6 +42,27 @@ static BOOL is_rect_valid(const RECTANGLE_16* rect, size_t width, size_t height)
return TRUE;
}
+static BOOL is_within_surface(const gdiGfxSurface* surface, const RDPGFX_SURFACE_COMMAND* cmd)
+{
+ RECTANGLE_16 rect;
+ if (!surface || !cmd)
+ return FALSE;
+ rect.left = cmd->left;
+ rect.top = cmd->top;
+ rect.right = cmd->right;
+ rect.bottom = cmd->bottom;
+ if (!is_rect_valid(&rect, surface->width, surface->height))
+ {
+ WLog_ERR(TAG,
+ "%s: Command rect %" PRIu32 "x" PRIu32 "-" PRIu32 "x" PRIu32
+ " not within bounds of " PRIu32 "x" PRIu32,
+ __FUNCTION__, rect.left, rect.top, cmd->width, cmd->height, surface->width,
+ surface->height);
+ return FALSE;
+ }
+ return TRUE;
+}
+
static DWORD gfx_align_scanline(DWORD widthInBytes, DWORD alignment)
{
const UINT32 align = alignment;
@@ -259,6 +280,9 @@ static UINT gdi_SurfaceCommand_Uncompressed(rdpGdi* gdi, RdpgfxClientContext* co
return ERROR_NOT_FOUND;
}
+ if (!is_within_surface(surface, cmd))
+ return ERROR_INVALID_DATA;
+
if (!freerdp_image_copy(surface->data, surface->format, surface->scanline, cmd->left, cmd->top,
cmd->width, cmd->height, cmd->data, cmd->format, 0, 0, 0, NULL,
FREERDP_FLIP_NONE))
@@ -414,6 +438,9 @@ static UINT gdi_SurfaceCommand_Planar(rdpGdi* gdi, RdpgfxClientContext* context,
DstData = surface->data;
+ if (!is_within_surface(surface, cmd))
+ return ERROR_INVALID_DATA;
+
if (!planar_decompress(surface->codecs->planar, cmd->data, cmd->length, cmd->width, cmd->height,
DstData, surface->format, surface->scanline, cmd->left, cmd->top,
cmd->width, cmd->height, FALSE))
@@ -686,6 +713,9 @@ static UINT gdi_SurfaceCommand_Alpha(rdpGdi* gdi, RdpgfxClientContext* context,
return ERROR_NOT_FOUND;
}
+ if (!is_within_surface(surface, cmd))
+ return ERROR_INVALID_DATA;
+
Stream_Read_UINT16(&s, alphaSig);
Stream_Read_UINT16(&s, compressed);
@@ -815,6 +845,9 @@ static UINT gdi_SurfaceCommand_Progressive(rdpGdi* gdi, RdpgfxClientContext* con
return ERROR_NOT_FOUND;
}
+ if (!is_within_surface(surface, cmd))
+ return ERROR_INVALID_DATA;
+
rc = progressive_create_surface_context(surface->codecs->progressive, cmd->surfaceId,
surface->width, surface->height);
--
2.30.2
|