]> git.proxmox.com Git - pve-qemu.git/blob - debian/patches/extra/0040-nbd-server-get-rid-of-nbd_negotiate_read-and-friends.patch
638e22f9364a459a907a0dc0f7709cc27389594b
[pve-qemu.git] / debian / patches / extra / 0040-nbd-server-get-rid-of-nbd_negotiate_read-and-friends.patch
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
48 index c2a5909ad6..ddf93d4717 100644
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 }
239 @@ -516,7 +452,7 @@ static int nbd_negotiate_options(NBDClient *client)
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,
248 @@ -554,7 +490,7 @@ static int nbd_negotiate_options(NBDClient *client)
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) {
257 @@ -573,7 +509,7 @@ static int nbd_negotiate_options(NBDClient *client)
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,
266 @@ -662,12 +598,12 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data)
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 }
281 @@ -682,7 +618,7 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data)
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 --
291 2.11.0
292