1 From 9235c84e0fbbf5c19305e82fc1607393b35b74ef Mon Sep 17 00:00:00 2001
2 From: Frediano Ziglio <fziglio@redhat.com>
3 Date: Tue, 8 Sep 2015 10:04:10 +0100
4 Subject: [PATCH 09/19] Fix race in red_get_image
6 Do not read multiple times data from guest as this could be changed
8 This causes races and security problems if these data are used for
9 buffer allocation or checks.
11 Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
12 Acked-by: Christophe Fergeau <cfergeau@redhat.com>
14 server/red_parse_qxl.c | 18 ++++++++++--------
15 1 file changed, 10 insertions(+), 8 deletions(-)
17 --- a/server/red_parse_qxl.c
18 +++ b/server/red_parse_qxl.c
19 @@ -397,6 +397,7 @@ static SpiceImage *red_get_image(RedMemS
20 uint64_t bitmap_size, size;
23 + QXLPHYSICAL palette;
27 @@ -422,12 +423,16 @@ static SpiceImage *red_get_image(RedMemS
28 switch (red->descriptor.type) {
29 case SPICE_IMAGE_TYPE_BITMAP:
30 red->u.bitmap.format = qxl->bitmap.format;
31 - if (!bitmap_fmt_is_rgb(qxl->bitmap.format) && !qxl->bitmap.palette && !is_mask) {
32 + red->u.bitmap.x = qxl->bitmap.x;
33 + red->u.bitmap.y = qxl->bitmap.y;
34 + red->u.bitmap.stride = qxl->bitmap.stride;
35 + palette = qxl->bitmap.palette;
36 + if (!bitmap_fmt_is_rgb(red->u.bitmap.format) && !palette && !is_mask) {
37 spice_warning("guest error: missing palette on bitmap format=%d\n",
38 red->u.bitmap.format);
41 - if (qxl->bitmap.x == 0 || qxl->bitmap.y == 0) {
42 + if (red->u.bitmap.x == 0 || red->u.bitmap.y == 0) {
43 spice_warning("guest error: zero area bitmap\n");
46 @@ -435,23 +440,20 @@ static SpiceImage *red_get_image(RedMemS
47 if (qxl_flags & QXL_BITMAP_TOP_DOWN) {
48 red->u.bitmap.flags = SPICE_BITMAP_FLAGS_TOP_DOWN;
50 - red->u.bitmap.x = qxl->bitmap.x;
51 - red->u.bitmap.y = qxl->bitmap.y;
52 - red->u.bitmap.stride = qxl->bitmap.stride;
53 if (!bitmap_consistent(&red->u.bitmap)) {
56 - if (qxl->bitmap.palette) {
60 - qp = (QXLPalette *)get_virt(slots, qxl->bitmap.palette,
61 + qp = (QXLPalette *)get_virt(slots, palette,
62 sizeof(*qp), group_id, &error);
66 num_ents = qp->num_ents;
67 if (!validate_virt(slots, (intptr_t)qp->ents,
68 - get_memslot_id(slots, qxl->bitmap.palette),
69 + get_memslot_id(slots, palette),
70 num_ents * sizeof(qp->ents[0]), group_id)) {