]>
Commit | Line | Data |
---|---|---|
b45e13fe AD |
1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
2 | From: Eric Blake <eblake@redhat.com> | |
3 | Date: Wed, 19 Jul 2017 18:02:02 +0200 | |
4 | Subject: [PATCH] nbd/server: get rid of nbd_negotiate_read and friends | |
5 | ||
6 | RH-Author: Eric Blake <eblake@redhat.com> | |
7 | Message-id: <20170719180202.23329-5-eblake@redhat.com> | |
8 | Patchwork-id: 75816 | |
9 | O-Subject: [RHEV-7.4.z qemu-kvm-rhev PATCH 4/4] nbd/server: get rid of nbd_negotiate_read and friends | |
10 | Bugzilla: 1467509 | |
11 | RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com> | |
12 | RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com> | |
13 | RH-Acked-by: Jeffrey Cody <jcody@redhat.com> | |
14 | ||
15 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | |
16 | ||
17 | Functions nbd_negotiate_{read,write,drop_sync} were introduced in | |
18 | 1a6245a5b, when nbd_rwv (was nbd_wr_sync) was working through | |
19 | qemu_co_sendv_recvv (the path is nbd_wr_sync -> qemu_co_{recv/send} -> | |
20 | qemu_co_send_recv -> qemu_co_sendv_recvv), which just yields, without | |
21 | setting any handlers. But starting from ff82911cd nbd_rwv (was | |
22 | nbd_wr_syncv) works through qio_channel_yield() which sets handlers, so | |
23 | watchers are redundant in nbd_negotiate_{read,write,drop_sync}, then, | |
24 | let's just use nbd_{read,write,drop} functions. | |
25 | ||
26 | Functions nbd_{read,write,drop} has errp parameter, which is unused in | |
27 | this patch. This will be fixed later. | |
28 | ||
29 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | |
30 | Reviewed-by: Eric Blake <eblake@redhat.com> | |
31 | Message-Id: <20170602150150.258222-4-vsementsov@virtuozzo.com> | |
32 | Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> | |
33 | (cherry picked from commit 2b0bbc4f8809c972bad134bc1a2570dbb01dea0b) | |
34 | ||
35 | Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com> | |
36 | ||
37 | Conflicts: | |
38 | nbd/server.c - missing errp addition (e44ed99) and bulk | |
39 | rename (d1fdf25) | |
40 | Fixes CVE-2017-7539 | |
41 | ||
42 | Signed-off-by: Eric Blake <eblake@redhat.com> | |
43 | --- | |
44 | nbd/server.c | 106 ++++++++++++----------------------------------------------- | |
45 | 1 file changed, 21 insertions(+), 85 deletions(-) | |
46 | ||
47 | diff --git a/nbd/server.c b/nbd/server.c | |
507c6de3 | 48 | index c2a5909ad6..ddf93d4717 100644 |
b45e13fe AD |
49 | --- a/nbd/server.c |
50 | +++ b/nbd/server.c | |
51 | @@ -104,69 +104,6 @@ struct NBDClient { | |
52 | ||
53 | static void nbd_client_receive_next_request(NBDClient *client); | |
54 | ||
55 | -static gboolean nbd_negotiate_continue(QIOChannel *ioc, | |
56 | - GIOCondition condition, | |
57 | - void *opaque) | |
58 | -{ | |
59 | - qemu_coroutine_enter(opaque); | |
60 | - return TRUE; | |
61 | -} | |
62 | - | |
63 | -static int nbd_negotiate_read(QIOChannel *ioc, void *buffer, size_t size) | |
64 | -{ | |
65 | - ssize_t ret; | |
66 | - guint watch; | |
67 | - | |
68 | - assert(qemu_in_coroutine()); | |
69 | - /* Negotiation are always in main loop. */ | |
70 | - watch = qio_channel_add_watch(ioc, | |
71 | - G_IO_IN, | |
72 | - nbd_negotiate_continue, | |
73 | - qemu_coroutine_self(), | |
74 | - NULL); | |
75 | - ret = read_sync(ioc, buffer, size); | |
76 | - g_source_remove(watch); | |
77 | - return ret; | |
78 | - | |
79 | -} | |
80 | - | |
81 | -static int nbd_negotiate_write(QIOChannel *ioc, const void *buffer, size_t size) | |
82 | -{ | |
83 | - ssize_t ret; | |
84 | - guint watch; | |
85 | - | |
86 | - assert(qemu_in_coroutine()); | |
87 | - /* Negotiation are always in main loop. */ | |
88 | - watch = qio_channel_add_watch(ioc, | |
89 | - G_IO_OUT, | |
90 | - nbd_negotiate_continue, | |
91 | - qemu_coroutine_self(), | |
92 | - NULL); | |
93 | - ret = write_sync(ioc, buffer, size); | |
94 | - g_source_remove(watch); | |
95 | - return ret; | |
96 | -} | |
97 | - | |
98 | -static int nbd_negotiate_drop_sync(QIOChannel *ioc, size_t size) | |
99 | -{ | |
100 | - ssize_t ret; | |
101 | - uint8_t *buffer = g_malloc(MIN(65536, size)); | |
102 | - | |
103 | - while (size > 0) { | |
104 | - size_t count = MIN(65536, size); | |
105 | - ret = nbd_negotiate_read(ioc, buffer, count); | |
106 | - if (ret < 0) { | |
107 | - g_free(buffer); | |
108 | - return ret; | |
109 | - } | |
110 | - | |
111 | - size -= count; | |
112 | - } | |
113 | - | |
114 | - g_free(buffer); | |
115 | - return 0; | |
116 | -} | |
117 | - | |
118 | /* Basic flow for negotiation | |
119 | ||
120 | Server Client | |
121 | @@ -205,22 +142,22 @@ static int nbd_negotiate_send_rep_len(QIOChannel *ioc, uint32_t type, | |
122 | type, opt, len); | |
123 | ||
124 | magic = cpu_to_be64(NBD_REP_MAGIC); | |
125 | - if (nbd_negotiate_write(ioc, &magic, sizeof(magic)) < 0) { | |
126 | + if (write_sync(ioc, &magic, sizeof(magic)) < 0) { | |
127 | LOG("write failed (rep magic)"); | |
128 | return -EINVAL; | |
129 | } | |
130 | opt = cpu_to_be32(opt); | |
131 | - if (nbd_negotiate_write(ioc, &opt, sizeof(opt)) < 0) { | |
132 | + if (write_sync(ioc, &opt, sizeof(opt)) < 0) { | |
133 | LOG("write failed (rep opt)"); | |
134 | return -EINVAL; | |
135 | } | |
136 | type = cpu_to_be32(type); | |
137 | - if (nbd_negotiate_write(ioc, &type, sizeof(type)) < 0) { | |
138 | + if (write_sync(ioc, &type, sizeof(type)) < 0) { | |
139 | LOG("write failed (rep type)"); | |
140 | return -EINVAL; | |
141 | } | |
142 | len = cpu_to_be32(len); | |
143 | - if (nbd_negotiate_write(ioc, &len, sizeof(len)) < 0) { | |
144 | + if (write_sync(ioc, &len, sizeof(len)) < 0) { | |
145 | LOG("write failed (rep data length)"); | |
146 | return -EINVAL; | |
147 | } | |
148 | @@ -255,7 +192,7 @@ nbd_negotiate_send_rep_err(QIOChannel *ioc, uint32_t type, | |
149 | if (ret < 0) { | |
150 | goto out; | |
151 | } | |
152 | - if (nbd_negotiate_write(ioc, msg, len) < 0) { | |
153 | + if (write_sync(ioc, msg, len) < 0) { | |
154 | LOG("write failed (error message)"); | |
155 | ret = -EIO; | |
156 | } else { | |
157 | @@ -286,15 +223,15 @@ static int nbd_negotiate_send_rep_list(QIOChannel *ioc, NBDExport *exp) | |
158 | } | |
159 | ||
160 | len = cpu_to_be32(name_len); | |
161 | - if (nbd_negotiate_write(ioc, &len, sizeof(len)) < 0) { | |
162 | + if (write_sync(ioc, &len, sizeof(len)) < 0) { | |
163 | LOG("write failed (name length)"); | |
164 | return -EINVAL; | |
165 | } | |
166 | - if (nbd_negotiate_write(ioc, name, name_len) < 0) { | |
167 | + if (write_sync(ioc, name, name_len) < 0) { | |
168 | LOG("write failed (name buffer)"); | |
169 | return -EINVAL; | |
170 | } | |
171 | - if (nbd_negotiate_write(ioc, desc, desc_len) < 0) { | |
172 | + if (write_sync(ioc, desc, desc_len) < 0) { | |
173 | LOG("write failed (description buffer)"); | |
174 | return -EINVAL; | |
175 | } | |
176 | @@ -308,7 +245,7 @@ static int nbd_negotiate_handle_list(NBDClient *client, uint32_t length) | |
177 | NBDExport *exp; | |
178 | ||
179 | if (length) { | |
180 | - if (nbd_negotiate_drop_sync(client->ioc, length) < 0) { | |
181 | + if (nbd_drop(client->ioc, length) < 0) { | |
182 | return -EIO; | |
183 | } | |
184 | return nbd_negotiate_send_rep_err(client->ioc, | |
185 | @@ -339,7 +276,7 @@ static int nbd_negotiate_handle_export_name(NBDClient *client, uint32_t length) | |
186 | LOG("Bad length received"); | |
187 | goto fail; | |
188 | } | |
189 | - if (nbd_negotiate_read(client->ioc, name, length) < 0) { | |
190 | + if (read_sync(client->ioc, name, length) < 0) { | |
191 | LOG("read failed"); | |
192 | goto fail; | |
193 | } | |
194 | @@ -372,7 +309,7 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client, | |
195 | TRACE("Setting up TLS"); | |
196 | ioc = client->ioc; | |
197 | if (length) { | |
198 | - if (nbd_negotiate_drop_sync(ioc, length) < 0) { | |
199 | + if (nbd_drop(ioc, length) < 0) { | |
200 | return NULL; | |
201 | } | |
202 | nbd_negotiate_send_rep_err(ioc, NBD_REP_ERR_INVALID, NBD_OPT_STARTTLS, | |
203 | @@ -436,7 +373,7 @@ static int nbd_negotiate_options(NBDClient *client) | |
204 | ... Rest of request | |
205 | */ | |
206 | ||
207 | - if (nbd_negotiate_read(client->ioc, &flags, sizeof(flags)) < 0) { | |
208 | + if (read_sync(client->ioc, &flags, sizeof(flags)) < 0) { | |
209 | LOG("read failed"); | |
210 | return -EIO; | |
211 | } | |
212 | @@ -462,7 +399,7 @@ static int nbd_negotiate_options(NBDClient *client) | |
213 | uint32_t clientflags, length; | |
214 | uint64_t magic; | |
215 | ||
216 | - if (nbd_negotiate_read(client->ioc, &magic, sizeof(magic)) < 0) { | |
217 | + if (read_sync(client->ioc, &magic, sizeof(magic)) < 0) { | |
218 | LOG("read failed"); | |
219 | return -EINVAL; | |
220 | } | |
221 | @@ -472,15 +409,14 @@ static int nbd_negotiate_options(NBDClient *client) | |
222 | return -EINVAL; | |
223 | } | |
224 | ||
225 | - if (nbd_negotiate_read(client->ioc, &clientflags, | |
226 | - sizeof(clientflags)) < 0) | |
227 | + if (read_sync(client->ioc, &clientflags, sizeof(clientflags)) < 0) | |
228 | { | |
229 | LOG("read failed"); | |
230 | return -EINVAL; | |
231 | } | |
232 | clientflags = be32_to_cpu(clientflags); | |
233 | ||
234 | - if (nbd_negotiate_read(client->ioc, &length, sizeof(length)) < 0) { | |
235 | + if (read_sync(client->ioc, &length, sizeof(length)) < 0) { | |
236 | LOG("read failed"); | |
237 | return -EINVAL; | |
238 | } | |
507c6de3 | 239 | @@ -516,7 +452,7 @@ static int nbd_negotiate_options(NBDClient *client) |
b45e13fe AD |
240 | return -EINVAL; |
241 | ||
242 | default: | |
243 | - if (nbd_negotiate_drop_sync(client->ioc, length) < 0) { | |
244 | + if (nbd_drop(client->ioc, length) < 0) { | |
245 | return -EIO; | |
246 | } | |
247 | ret = nbd_negotiate_send_rep_err(client->ioc, | |
507c6de3 | 248 | @@ -554,7 +490,7 @@ static int nbd_negotiate_options(NBDClient *client) |
b45e13fe AD |
249 | return nbd_negotiate_handle_export_name(client, length); |
250 | ||
251 | case NBD_OPT_STARTTLS: | |
252 | - if (nbd_negotiate_drop_sync(client->ioc, length) < 0) { | |
253 | + if (nbd_drop(client->ioc, length) < 0) { | |
254 | return -EIO; | |
255 | } | |
256 | if (client->tlscreds) { | |
507c6de3 | 257 | @@ -573,7 +509,7 @@ static int nbd_negotiate_options(NBDClient *client) |
b45e13fe AD |
258 | } |
259 | break; | |
260 | default: | |
261 | - if (nbd_negotiate_drop_sync(client->ioc, length) < 0) { | |
262 | + if (nbd_drop(client->ioc, length) < 0) { | |
263 | return -EIO; | |
264 | } | |
265 | ret = nbd_negotiate_send_rep_err(client->ioc, | |
507c6de3 | 266 | @@ -662,12 +598,12 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data) |
b45e13fe AD |
267 | TRACE("TLS cannot be enabled with oldstyle protocol"); |
268 | goto fail; | |
269 | } | |
270 | - if (nbd_negotiate_write(client->ioc, buf, sizeof(buf)) < 0) { | |
271 | + if (write_sync(client->ioc, buf, sizeof(buf)) < 0) { | |
272 | LOG("write failed"); | |
273 | goto fail; | |
274 | } | |
275 | } else { | |
276 | - if (nbd_negotiate_write(client->ioc, buf, 18) < 0) { | |
277 | + if (write_sync(client->ioc, buf, 18) < 0) { | |
278 | LOG("write failed"); | |
279 | goto fail; | |
280 | } | |
507c6de3 | 281 | @@ -682,7 +618,7 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data) |
b45e13fe AD |
282 | stq_be_p(buf + 18, client->exp->size); |
283 | stw_be_p(buf + 26, client->exp->nbdflags | myflags); | |
284 | len = client->no_zeroes ? 10 : sizeof(buf) - 18; | |
285 | - if (nbd_negotiate_write(client->ioc, buf + 18, len) < 0) { | |
286 | + if (write_sync(client->ioc, buf + 18, len) < 0) { | |
287 | LOG("write failed"); | |
288 | goto fail; | |
289 | } | |
290 | -- | |
507c6de3 | 291 | 2.11.0 |
b45e13fe | 292 |