]> git.proxmox.com Git - pve-libspice-server.git/blob - debian/patches/CVE-2015-5260_CVE-2015-5261/0012-Fix-race-condition-in-red_get_data_chunks_ptr.patch
fix CVE-2015-3247, CVE-2015-5260, CVE-2015-5261
[pve-libspice-server.git] / debian / patches / CVE-2015-5260_CVE-2015-5261 / 0012-Fix-race-condition-in-red_get_data_chunks_ptr.patch
1 From 3738478ed7065fe05f3ee4848f8a7fcdf40aa920 Mon Sep 17 00:00:00 2001
2 From: Frediano Ziglio <fziglio@redhat.com>
3 Date: Tue, 8 Sep 2015 12:12:19 +0100
4 Subject: [PATCH 12/19] Fix race condition in red_get_data_chunks_ptr
5
6 Do not read multiple times data from guest as this can be changed by
7 other guest vcpus. This causes races and security problems if these
8 data are used for buffer allocation or checks.
9
10 Actually, the 'data' member can't change during read as it is just a
11 pointer to a fixed array contained in qxl. However, this change will
12 make it clear that there can be no race condition.
13
14 Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
15 ---
16 server/red_parse_qxl.c | 17 ++++++++++-------
17 1 file changed, 10 insertions(+), 7 deletions(-)
18
19 diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
20 index cfa21f9..2863ae2 100644
21 --- a/server/red_parse_qxl.c
22 +++ b/server/red_parse_qxl.c
23 @@ -102,30 +102,33 @@ static size_t red_get_data_chunks_ptr(RedMemSlotInfo *slots, int group_id,
24 RedDataChunk *red_prev;
25 size_t data_size = 0;
26 int error;
27 + QXLPHYSICAL next_chunk;
28
29 red->data_size = qxl->data_size;
30 data_size += red->data_size;
31 - if (!validate_virt(slots, (intptr_t)qxl->data, memslot_id, red->data_size, group_id)) {
32 + red->data = qxl->data;
33 + if (!validate_virt(slots, (intptr_t)red->data, memslot_id, red->data_size, group_id)) {
34 + red->data = NULL;
35 return 0;
36 }
37 - red->data = qxl->data;
38 red->prev_chunk = NULL;
39
40 - while (qxl->next_chunk) {
41 + while ((next_chunk = qxl->next_chunk) != 0) {
42 red_prev = red;
43 red = spice_new(RedDataChunk, 1);
44 - memslot_id = get_memslot_id(slots, qxl->next_chunk);
45 - qxl = (QXLDataChunk *)get_virt(slots, qxl->next_chunk, sizeof(*qxl), group_id,
46 + memslot_id = get_memslot_id(slots, next_chunk);
47 + qxl = (QXLDataChunk *)get_virt(slots, next_chunk, sizeof(*qxl), group_id,
48 &error);
49 if (error) {
50 return 0;
51 }
52 red->data_size = qxl->data_size;
53 data_size += red->data_size;
54 - if (!validate_virt(slots, (intptr_t)qxl->data, memslot_id, red->data_size, group_id)) {
55 + red->data = qxl->data;
56 + if (!validate_virt(slots, (intptr_t)red->data, memslot_id, red->data_size, group_id)) {
57 + red->data = NULL;
58 return 0;
59 }
60 - red->data = qxl->data;
61 red->prev_chunk = red_prev;
62 red_prev->next_chunk = red;
63 }
64 --
65 2.6.1
66