]>
Commit | Line | Data |
---|---|---|
907c9f0e DM |
1 | From 1eb93baa3c594e1214b1c92bbad8a06e9c7e2d12 Mon Sep 17 00:00:00 2001 |
2 | From: Frediano Ziglio <fziglio@redhat.com> | |
3 | Date: Tue, 8 Sep 2015 16:02:59 +0100 | |
4 | Subject: [PATCH 05/19] Check properly surface to be created | |
5 | ||
6 | Check format is valid. | |
7 | Check stride is at least the size of required bytes for a row. | |
8 | ||
9 | Signed-off-by: Frediano Ziglio <fziglio@redhat.com> | |
10 | Acked-by: Christophe Fergeau <cfergeau@redhat.com> | |
11 | --- | |
12 | server/red_parse_qxl.c | 35 ++++++++++++++++++++++++++++++++++- | |
13 | 1 file changed, 34 insertions(+), 1 deletion(-) | |
14 | ||
15 | --- a/server/red_parse_qxl.c | |
16 | +++ b/server/red_parse_qxl.c | |
17 | @@ -1220,12 +1220,30 @@ void red_put_message(RedMessage *red) | |
18 | /* nothing yet */ | |
19 | } | |
20 | ||
21 | +static unsigned int surface_format_to_bpp(uint32_t format) | |
22 | +{ | |
23 | + switch (format) { | |
24 | + case SPICE_SURFACE_FMT_1_A: | |
25 | + return 1; | |
26 | + case SPICE_SURFACE_FMT_8_A: | |
27 | + return 8; | |
28 | + case SPICE_SURFACE_FMT_16_555: | |
29 | + case SPICE_SURFACE_FMT_16_565: | |
30 | + return 16; | |
31 | + case SPICE_SURFACE_FMT_32_xRGB: | |
32 | + case SPICE_SURFACE_FMT_32_ARGB: | |
33 | + return 32; | |
34 | + } | |
35 | + return 0; | |
36 | +} | |
37 | + | |
38 | int red_get_surface_cmd(RedMemSlotInfo *slots, int group_id, | |
39 | RedSurfaceCmd *red, QXLPHYSICAL addr) | |
40 | { | |
41 | QXLSurfaceCmd *qxl; | |
42 | uint64_t size; | |
43 | int error; | |
44 | + unsigned int bpp; | |
45 | ||
46 | qxl = (QXLSurfaceCmd *)get_virt(slots, addr, sizeof(*qxl), group_id, | |
47 | &error); | |
48 | @@ -1244,9 +1262,24 @@ int red_get_surface_cmd(RedMemSlotInfo * | |
49 | red->u.surface_create.width = qxl->u.surface_create.width; | |
50 | red->u.surface_create.height = qxl->u.surface_create.height; | |
51 | red->u.surface_create.stride = qxl->u.surface_create.stride; | |
52 | + bpp = surface_format_to_bpp(red->u.surface_create.format); | |
53 | + | |
54 | + /* check if format is valid */ | |
55 | + if (!bpp) { | |
56 | + return 1; | |
57 | + } | |
58 | + | |
59 | + /* check stride is larger than required bytes */ | |
60 | + size = ((uint64_t) red->u.surface_create.width * bpp + 7u) / 8u; | |
61 | + /* the uint32_t conversion is here to avoid problems with -2^31 value */ | |
62 | + if (red->u.surface_create.stride == G_MININT32 | |
63 | + || size > (uint32_t) abs(red->u.surface_create.stride)) { | |
64 | + return 1; | |
65 | + } | |
66 | + | |
67 | /* the multiplication can overflow, also abs(-2^31) may return a negative value */ | |
68 | size = (uint64_t) red->u.surface_create.height * abs(red->u.surface_create.stride); | |
69 | - if (size > MAX_DATA_CHUNK || red->u.surface_create.stride == G_MININT32) { | |
70 | + if (size > MAX_DATA_CHUNK) { | |
71 | return 1; | |
72 | } | |
73 | red->u.surface_create.data = |