]>
Commit | Line | Data |
---|---|---|
907c9f0e DM |
1 | From f3605979ce3b33d60c33b59334b53618e6d8662a Mon Sep 17 00:00:00 2001 |
2 | From: Frediano Ziglio <fziglio@redhat.com> | |
3 | Date: Tue, 8 Sep 2015 12:14:55 +0100 | |
4 | Subject: [PATCH 13/19] Prevent memory leak if red_get_data_chunks_ptr fails | |
5 | ||
6 | Free linked list if client tries to do nasty things | |
7 | ||
8 | Signed-off-by: Frediano Ziglio <fziglio@redhat.com> | |
9 | Acked-by: Christophe Fergeau <cfergeau@redhat.com> | |
10 | --- | |
11 | server/red_parse_qxl.c | 31 ++++++++++++++++++++----------- | |
12 | 1 file changed, 20 insertions(+), 11 deletions(-) | |
13 | ||
14 | diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c | |
15 | index 2863ae2..f425869 100644 | |
16 | --- a/server/red_parse_qxl.c | |
17 | +++ b/server/red_parse_qxl.c | |
18 | @@ -107,34 +107,43 @@ static size_t red_get_data_chunks_ptr(RedMemSlotInfo *slots, int group_id, | |
19 | red->data_size = qxl->data_size; | |
20 | data_size += red->data_size; | |
21 | red->data = qxl->data; | |
22 | + red->prev_chunk = red->next_chunk = NULL; | |
23 | if (!validate_virt(slots, (intptr_t)red->data, memslot_id, red->data_size, group_id)) { | |
24 | red->data = NULL; | |
25 | return 0; | |
26 | } | |
27 | - red->prev_chunk = NULL; | |
28 | ||
29 | while ((next_chunk = qxl->next_chunk) != 0) { | |
30 | red_prev = red; | |
31 | - red = spice_new(RedDataChunk, 1); | |
32 | + red = spice_new0(RedDataChunk, 1); | |
33 | + red->prev_chunk = red_prev; | |
34 | + red_prev->next_chunk = red; | |
35 | + | |
36 | memslot_id = get_memslot_id(slots, next_chunk); | |
37 | qxl = (QXLDataChunk *)get_virt(slots, next_chunk, sizeof(*qxl), group_id, | |
38 | &error); | |
39 | - if (error) { | |
40 | - return 0; | |
41 | - } | |
42 | + if (error) | |
43 | + goto error; | |
44 | red->data_size = qxl->data_size; | |
45 | data_size += red->data_size; | |
46 | red->data = qxl->data; | |
47 | - if (!validate_virt(slots, (intptr_t)red->data, memslot_id, red->data_size, group_id)) { | |
48 | - red->data = NULL; | |
49 | - return 0; | |
50 | - } | |
51 | - red->prev_chunk = red_prev; | |
52 | - red_prev->next_chunk = red; | |
53 | + if (!validate_virt(slots, (intptr_t)red->data, memslot_id, red->data_size, group_id)) | |
54 | + goto error; | |
55 | } | |
56 | ||
57 | red->next_chunk = NULL; | |
58 | return data_size; | |
59 | + | |
60 | +error: | |
61 | + while (red->prev_chunk) { | |
62 | + red_prev = red->prev_chunk; | |
63 | + free(red); | |
64 | + red = red_prev; | |
65 | + } | |
66 | + red->data_size = 0; | |
67 | + red->next_chunk = NULL; | |
68 | + red->data = NULL; | |
69 | + return 0; | |
70 | } | |
71 | ||
72 | static size_t red_get_data_chunks(RedMemSlotInfo *slots, int group_id, | |
73 | -- | |
74 | 2.6.1 | |
75 |