diff options
Diffstat (limited to 'meta/recipes-devtools/qemu/qemu/CVE-2016-2858.patch')
-rw-r--r-- | meta/recipes-devtools/qemu/qemu/CVE-2016-2858.patch | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2016-2858.patch b/meta/recipes-devtools/qemu/qemu/CVE-2016-2858.patch new file mode 100644 index 0000000000..d5395e6152 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/CVE-2016-2858.patch | |||
@@ -0,0 +1,183 @@ | |||
1 | From 60253ed1e6ec6d8e5ef2efe7bf755f475dce9956 Mon Sep 17 00:00:00 2001 | ||
2 | From: Ladi Prosek <lprosek@redhat.com> | ||
3 | Date: Thu, 3 Mar 2016 09:37:18 +0100 | ||
4 | Subject: [PATCH] rng: add request queue support to rng-random | ||
5 | |||
6 | Requests are now created in the RngBackend parent class and the | ||
7 | code path is shared by both rng-egd and rng-random. | ||
8 | |||
9 | This commit fixes the rng-random implementation which processed | ||
10 | only one request at a time and simply discarded all but the most | ||
11 | recent one. In the guest this manifested as delayed completion | ||
12 | of reads from virtio-rng, i.e. a read was completed only after | ||
13 | another read was issued. | ||
14 | |||
15 | By switching rng-random to use the same request queue as rng-egd, | ||
16 | the unsafe stack-based allocation of the entropy buffer is | ||
17 | eliminated and replaced with g_malloc. | ||
18 | |||
19 | Signed-off-by: Ladi Prosek <lprosek@redhat.com> | ||
20 | Reviewed-by: Amit Shah <amit.shah@redhat.com> | ||
21 | Message-Id: <1456994238-9585-5-git-send-email-lprosek@redhat.com> | ||
22 | Signed-off-by: Amit Shah <amit.shah@redhat.com> | ||
23 | |||
24 | Upstream-Status: Backport | ||
25 | CVE: CVE-2016-2858 | ||
26 | |||
27 | http://git.qemu.org/?p=qemu.git;a=commit;h=60253ed1e6ec6d8e5ef2efe7bf755f475 | ||
28 | Signed-off-by: Armin Kuster <akuster@mvista.com> | ||
29 | |||
30 | --- | ||
31 | backends/rng-egd.c | 16 ++-------------- | ||
32 | backends/rng-random.c | 43 +++++++++++++++++++------------------------ | ||
33 | backends/rng.c | 13 ++++++++++++- | ||
34 | include/sysemu/rng.h | 3 +-- | ||
35 | 4 files changed, 34 insertions(+), 41 deletions(-) | ||
36 | |||
37 | Index: qemu-2.5.0/backends/rng-egd.c | ||
38 | =================================================================== | ||
39 | --- qemu-2.5.0.orig/backends/rng-egd.c | ||
40 | +++ qemu-2.5.0/backends/rng-egd.c | ||
41 | @@ -26,20 +26,10 @@ typedef struct RngEgd | ||
42 | char *chr_name; | ||
43 | } RngEgd; | ||
44 | |||
45 | -static void rng_egd_request_entropy(RngBackend *b, size_t size, | ||
46 | - EntropyReceiveFunc *receive_entropy, | ||
47 | - void *opaque) | ||
48 | +static void rng_egd_request_entropy(RngBackend *b, RngRequest *req) | ||
49 | { | ||
50 | RngEgd *s = RNG_EGD(b); | ||
51 | - RngRequest *req; | ||
52 | - | ||
53 | - req = g_malloc(sizeof(*req)); | ||
54 | - | ||
55 | - req->offset = 0; | ||
56 | - req->size = size; | ||
57 | - req->receive_entropy = receive_entropy; | ||
58 | - req->opaque = opaque; | ||
59 | - req->data = g_malloc(req->size); | ||
60 | + size_t size = req->size; | ||
61 | |||
62 | while (size > 0) { | ||
63 | uint8_t header[2]; | ||
64 | @@ -53,8 +43,6 @@ static void rng_egd_request_entropy(RngB | ||
65 | |||
66 | size -= len; | ||
67 | } | ||
68 | - | ||
69 | - s->parent.requests = g_slist_append(s->parent.requests, req); | ||
70 | } | ||
71 | |||
72 | static int rng_egd_chr_can_read(void *opaque) | ||
73 | Index: qemu-2.5.0/backends/rng-random.c | ||
74 | =================================================================== | ||
75 | --- qemu-2.5.0.orig/backends/rng-random.c | ||
76 | +++ qemu-2.5.0/backends/rng-random.c | ||
77 | @@ -21,10 +21,6 @@ struct RndRandom | ||
78 | |||
79 | int fd; | ||
80 | char *filename; | ||
81 | - | ||
82 | - EntropyReceiveFunc *receive_func; | ||
83 | - void *opaque; | ||
84 | - size_t size; | ||
85 | }; | ||
86 | |||
87 | /** | ||
88 | @@ -37,36 +33,35 @@ struct RndRandom | ||
89 | static void entropy_available(void *opaque) | ||
90 | { | ||
91 | RndRandom *s = RNG_RANDOM(opaque); | ||
92 | - uint8_t buffer[s->size]; | ||
93 | - ssize_t len; | ||
94 | |||
95 | - len = read(s->fd, buffer, s->size); | ||
96 | - if (len < 0 && errno == EAGAIN) { | ||
97 | - return; | ||
98 | - } | ||
99 | - g_assert(len != -1); | ||
100 | + while (s->parent.requests != NULL) { | ||
101 | + RngRequest *req = s->parent.requests->data; | ||
102 | + ssize_t len; | ||
103 | + | ||
104 | + len = read(s->fd, req->data, req->size); | ||
105 | + if (len < 0 && errno == EAGAIN) { | ||
106 | + return; | ||
107 | + } | ||
108 | + g_assert(len != -1); | ||
109 | + | ||
110 | + req->receive_entropy(req->opaque, req->data, len); | ||
111 | |||
112 | - s->receive_func(s->opaque, buffer, len); | ||
113 | - s->receive_func = NULL; | ||
114 | + rng_backend_finalize_request(&s->parent, req); | ||
115 | + } | ||
116 | |||
117 | + /* We've drained all requests, the fd handler can be reset. */ | ||
118 | qemu_set_fd_handler(s->fd, NULL, NULL, NULL); | ||
119 | } | ||
120 | |||
121 | -static void rng_random_request_entropy(RngBackend *b, size_t size, | ||
122 | - EntropyReceiveFunc *receive_entropy, | ||
123 | - void *opaque) | ||
124 | +static void rng_random_request_entropy(RngBackend *b, RngRequest *req) | ||
125 | { | ||
126 | RndRandom *s = RNG_RANDOM(b); | ||
127 | |||
128 | - if (s->receive_func) { | ||
129 | - s->receive_func(s->opaque, NULL, 0); | ||
130 | + if (s->parent.requests == NULL) { | ||
131 | + /* If there are no pending requests yet, we need to | ||
132 | + * install our fd handler. */ | ||
133 | + qemu_set_fd_handler(s->fd, entropy_available, NULL, s); | ||
134 | } | ||
135 | - | ||
136 | - s->receive_func = receive_entropy; | ||
137 | - s->opaque = opaque; | ||
138 | - s->size = size; | ||
139 | - | ||
140 | - qemu_set_fd_handler(s->fd, entropy_available, NULL, s); | ||
141 | } | ||
142 | |||
143 | static void rng_random_opened(RngBackend *b, Error **errp) | ||
144 | Index: qemu-2.5.0/backends/rng.c | ||
145 | =================================================================== | ||
146 | --- qemu-2.5.0.orig/backends/rng.c | ||
147 | +++ qemu-2.5.0/backends/rng.c | ||
148 | @@ -19,9 +19,20 @@ void rng_backend_request_entropy(RngBack | ||
149 | void *opaque) | ||
150 | { | ||
151 | RngBackendClass *k = RNG_BACKEND_GET_CLASS(s); | ||
152 | + RngRequest *req; | ||
153 | |||
154 | if (k->request_entropy) { | ||
155 | - k->request_entropy(s, size, receive_entropy, opaque); | ||
156 | + req = g_malloc(sizeof(*req)); | ||
157 | + | ||
158 | + req->offset = 0; | ||
159 | + req->size = size; | ||
160 | + req->receive_entropy = receive_entropy; | ||
161 | + req->opaque = opaque; | ||
162 | + req->data = g_malloc(req->size); | ||
163 | + | ||
164 | + k->request_entropy(s, req); | ||
165 | + | ||
166 | + s->requests = g_slist_append(s->requests, req); | ||
167 | } | ||
168 | } | ||
169 | |||
170 | Index: qemu-2.5.0/include/sysemu/rng.h | ||
171 | =================================================================== | ||
172 | --- qemu-2.5.0.orig/include/sysemu/rng.h | ||
173 | +++ qemu-2.5.0/include/sysemu/rng.h | ||
174 | @@ -46,8 +46,7 @@ struct RngBackendClass | ||
175 | { | ||
176 | ObjectClass parent_class; | ||
177 | |||
178 | - void (*request_entropy)(RngBackend *s, size_t size, | ||
179 | - EntropyReceiveFunc *receive_entropy, void *opaque); | ||
180 | + void (*request_entropy)(RngBackend *s, RngRequest *req); | ||
181 | |||
182 | void (*opened)(RngBackend *s, Error **errp); | ||
183 | }; | ||