1 |
commit: 9212f510625a88c624d5d8d9456842091ee93305 |
2 |
Author: Aric Belsito <lluixhi <AT> gmail <DOT> com> |
3 |
AuthorDate: Thu Jul 27 17:59:01 2017 +0000 |
4 |
Commit: Aric Belsito <lluixhi <AT> gmail <DOT> com> |
5 |
CommitDate: Thu Jul 27 17:59:01 2017 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/musl.git/commit/?id=9212f510 |
7 |
|
8 |
app-emulation/qemu: restore patch |
9 |
|
10 |
deleted the wrong one.. |
11 |
|
12 |
app-emulation/qemu/Manifest | 2 +- |
13 |
.../qemu/files/qemu-2.9.0-CVE-2017-7493.patch | 174 ++++++ |
14 |
.../qemu/files/qemu-2.9.0-CVE-2017-7539.patch | 601 --------------------- |
15 |
3 files changed, 175 insertions(+), 602 deletions(-) |
16 |
|
17 |
diff --git a/app-emulation/qemu/Manifest b/app-emulation/qemu/Manifest |
18 |
index e4a3f79..e3f4bd2 100644 |
19 |
--- a/app-emulation/qemu/Manifest |
20 |
+++ b/app-emulation/qemu/Manifest |
21 |
@@ -9,7 +9,7 @@ AUX qemu-2.9.0-CVE-2017-10664.patch 1613 SHA256 5941cc41f0c02b185be3f6ba450f155d |
22 |
AUX qemu-2.9.0-CVE-2017-10806.patch 1450 SHA256 ef884e2ed3adb618273af1d036ed0c7e3a09599e3d042080bb4b5014c6bc54d7 SHA512 38fea2c1a2a5a224585a07a028a8c4cfc1bec4d943e85c13e01228062bf306a502b0948270863b226bc974832e3af18158904fbfc08ccdf1f72f06e7830780d5 WHIRLPOOL f02fb957016af684dc894f93ec0b7dcca3febb8d37882aae1e17d2aca9948e200a013ae467cb54c5555e76c73f124a37c95fde189a4492d88322802d8160310c |
23 |
AUX qemu-2.9.0-CVE-2017-11334.patch 1362 SHA256 bc2f3a50ad174e5453d0e4d1e14e9723b316e2339dc25ff31e27060ee13242bb SHA512 422296269ec29b3313c984947ac48b7179ce8e169131624d316589a621778f846b883e76cdfba50c62dc63ab5fede0ad0292704c1ca1cc9e1e7b3b01a153b8c8 WHIRLPOOL 504cf6b2ebfb11bf1471f920d101df28df59f1a585eac31ac278a366f2b769386bc7d100aa8386b3f8f45d5f5f700aa6625be3192eb4f1f3b77e69c6684cf74f |
24 |
AUX qemu-2.9.0-CVE-2017-11434.patch 912 SHA256 e8be3cb9261f8735ff2a50fb8b79ccfea85456c7a2e5a5702fcc5339463dc05a SHA512 db95d9459b9669e0981195fe15f16c4e74d5f00c03e1ce5e33541e005260e77fa114b1b3f30bc06d80b723a6361b704fb58709b25773c168c8aa8f5f96580ac9 WHIRLPOOL c68e25024ab3c1d01e5b53d0a7b1591110b96d78079bc940ec28da2e2770dac6b1f9bbaaeb97c88ea0e1b46db886f7035d81bde582750e560d136916ecdab8a2 |
25 |
-AUX qemu-2.9.0-CVE-2017-7539.patch 22018 SHA256 523d41e08a2aab888e3e63b4dda6a19e535fe6fba2bf08b6ead06498ca923f29 SHA512 5c81488aeae78307bee551a3a037f3b9cf55971a17c5df17f89f31224bdfa0a5e79141341314546256bffe542b781ad25151c54340a63c766086a578e5465825 WHIRLPOOL 085fc7e7d40c803a3caf15cdee77ce553b385919678ecf4bbcc3f532af5e482ca804a167af43e4f393da93aed88285690d84a3054c7f0df61d603d0046029dbc |
26 |
+AUX qemu-2.9.0-CVE-2017-7493.patch 5656 SHA256 77462d39e811e58d3761523a6c580485bdfca0e74adbd10cf24c254e0ece262a SHA512 2b01f2878c98e77997b645ba80e69b5db398ef1e8f2b66344818d3c9af35dd66d49041ef9ee8aa152bf3e94970b4db282cf53909cb13b2532bc0a104251b2e81 WHIRLPOOL 23c788c5a78e126a61bd277e9fa1511cc71b8fbdc83a5bf319c5fc424219cbcceefad737844e45c11a76e047f8a49853d0a85b267f24f7b23bb7276d0edf0451 |
27 |
AUX qemu-2.9.0-CVE-2017-8112.patch 696 SHA256 a4dcc2a94749a5c20ef38d4c7ce13cd1ffe46017c77eea29ced0bec5c232e6aa SHA512 840f5270332729e0149a4705bae5fcc16e9503a995d6bfa5033904a544add337ca8ccb1d2a36bb57cc198f6354f5253403f1c4f04cbd18c08b4e1a9d6af9e07f WHIRLPOOL 1ba4e75fdd0c767254c85754612da9e8ff9ba2e7ea0811f723844bec190946805cd59db83f347a3dea4296d2b58d2df4a8d99a492335ba818824348bcebdd556 |
28 |
AUX qemu-2.9.0-CVE-2017-8309.patch 595 SHA256 8231747fe4d9c97392fe44b117caccd07d320313dc27fad17ac658122113ced9 SHA512 4415c36acb4f0594de7fe0de2b669d03d6b54ae44eb7f1f285c36223a02cca887b57db27a43ab1cc2e7e193ee5bce2748f9d2056aa925e0cc8f2133e67168a74 WHIRLPOOL af4c5e9763a0e114e554a1c8be99ea79da0b634fdc9d87922c7713187f1f904bfcce103648d549bbb190e92443664dbb9bd7592d8137f2337be0f4b22d1f9bd1 |
29 |
AUX qemu-2.9.0-CVE-2017-8379.patch 2736 SHA256 f2f8910c8e1ce9fc9804f4fbbe978fee20ccbfccc5efe49f42cdaafa63c511ce SHA512 79e32f75d98ca4a92a5069b65c5b9cff16064255ed4d161e4e292b97373742c25d5ddc12dfffa627197fdb5e0808108b30d0182a9c060cd181723bd90c618d15 WHIRLPOOL 545c00189da3b252c80bb35c6b6d3368a02b36b06f2866838ddd9ebb9ccf2b608ae278ee192b6b3aef2966736afe9bcdd646c80c228ec5daef76b92bd2721bd5 |
30 |
|
31 |
diff --git a/app-emulation/qemu/files/qemu-2.9.0-CVE-2017-7493.patch b/app-emulation/qemu/files/qemu-2.9.0-CVE-2017-7493.patch |
32 |
new file mode 100644 |
33 |
index 0000000..346e771 |
34 |
--- /dev/null |
35 |
+++ b/app-emulation/qemu/files/qemu-2.9.0-CVE-2017-7493.patch |
36 |
@@ -0,0 +1,174 @@ |
37 |
+From 7a95434e0ca8a037fd8aa1a2e2461f92585eb77b Mon Sep 17 00:00:00 2001 |
38 |
+From: Greg Kurz <groug@××××.org> |
39 |
+Date: Fri, 5 May 2017 14:48:08 +0200 |
40 |
+Subject: [PATCH] 9pfs: local: forbid client access to metadata (CVE-2017-7493) |
41 |
+ |
42 |
+When using the mapped-file security mode, we shouldn't let the client mess |
43 |
+with the metadata. The current code already tries to hide the metadata dir |
44 |
+from the client by skipping it in local_readdir(). But the client can still |
45 |
+access or modify it through several other operations. This can be used to |
46 |
+escalate privileges in the guest. |
47 |
+ |
48 |
+Affected backend operations are: |
49 |
+- local_mknod() |
50 |
+- local_mkdir() |
51 |
+- local_open2() |
52 |
+- local_symlink() |
53 |
+- local_link() |
54 |
+- local_unlinkat() |
55 |
+- local_renameat() |
56 |
+- local_rename() |
57 |
+- local_name_to_path() |
58 |
+ |
59 |
+Other operations are safe because they are only passed a fid path, which |
60 |
+is computed internally in local_name_to_path(). |
61 |
+ |
62 |
+This patch converts all the functions listed above to fail and return |
63 |
+EINVAL when being passed the name of the metadata dir. This may look |
64 |
+like a poor choice for errno, but there's no such thing as an illegal |
65 |
+path name on Linux and I could not think of anything better. |
66 |
+ |
67 |
+This fixes CVE-2017-7493. |
68 |
+ |
69 |
+Reported-by: Leo Gaspard <leo@×××××××.io> |
70 |
+Signed-off-by: Greg Kurz <groug@××××.org> |
71 |
+Reviewed-by: Eric Blake <eblake@××××××.com> |
72 |
+--- |
73 |
+ hw/9pfs/9p-local.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- |
74 |
+ 1 file changed, 56 insertions(+), 2 deletions(-) |
75 |
+ |
76 |
+diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c |
77 |
+index f3ebca4f7a..a2486566af 100644 |
78 |
+--- a/hw/9pfs/9p-local.c |
79 |
++++ b/hw/9pfs/9p-local.c |
80 |
+@@ -452,6 +452,11 @@ static off_t local_telldir(FsContext *ctx, V9fsFidOpenState *fs) |
81 |
+ return telldir(fs->dir.stream); |
82 |
+ } |
83 |
+ |
84 |
++static bool local_is_mapped_file_metadata(FsContext *fs_ctx, const char *name) |
85 |
++{ |
86 |
++ return !strcmp(name, VIRTFS_META_DIR); |
87 |
++} |
88 |
++ |
89 |
+ static struct dirent *local_readdir(FsContext *ctx, V9fsFidOpenState *fs) |
90 |
+ { |
91 |
+ struct dirent *entry; |
92 |
+@@ -465,8 +470,8 @@ again: |
93 |
+ if (ctx->export_flags & V9FS_SM_MAPPED) { |
94 |
+ entry->d_type = DT_UNKNOWN; |
95 |
+ } else if (ctx->export_flags & V9FS_SM_MAPPED_FILE) { |
96 |
+- if (!strcmp(entry->d_name, VIRTFS_META_DIR)) { |
97 |
+- /* skp the meta data directory */ |
98 |
++ if (local_is_mapped_file_metadata(ctx, entry->d_name)) { |
99 |
++ /* skip the meta data directory */ |
100 |
+ goto again; |
101 |
+ } |
102 |
+ entry->d_type = DT_UNKNOWN; |
103 |
+@@ -559,6 +564,12 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path, |
104 |
+ int err = -1; |
105 |
+ int dirfd; |
106 |
+ |
107 |
++ if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE && |
108 |
++ local_is_mapped_file_metadata(fs_ctx, name)) { |
109 |
++ errno = EINVAL; |
110 |
++ return -1; |
111 |
++ } |
112 |
++ |
113 |
+ dirfd = local_opendir_nofollow(fs_ctx, dir_path->data); |
114 |
+ if (dirfd == -1) { |
115 |
+ return -1; |
116 |
+@@ -605,6 +616,12 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path, |
117 |
+ int err = -1; |
118 |
+ int dirfd; |
119 |
+ |
120 |
++ if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE && |
121 |
++ local_is_mapped_file_metadata(fs_ctx, name)) { |
122 |
++ errno = EINVAL; |
123 |
++ return -1; |
124 |
++ } |
125 |
++ |
126 |
+ dirfd = local_opendir_nofollow(fs_ctx, dir_path->data); |
127 |
+ if (dirfd == -1) { |
128 |
+ return -1; |
129 |
+@@ -694,6 +711,12 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name, |
130 |
+ int err = -1; |
131 |
+ int dirfd; |
132 |
+ |
133 |
++ if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE && |
134 |
++ local_is_mapped_file_metadata(fs_ctx, name)) { |
135 |
++ errno = EINVAL; |
136 |
++ return -1; |
137 |
++ } |
138 |
++ |
139 |
+ /* |
140 |
+ * Mark all the open to not follow symlinks |
141 |
+ */ |
142 |
+@@ -752,6 +775,12 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath, |
143 |
+ int err = -1; |
144 |
+ int dirfd; |
145 |
+ |
146 |
++ if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE && |
147 |
++ local_is_mapped_file_metadata(fs_ctx, name)) { |
148 |
++ errno = EINVAL; |
149 |
++ return -1; |
150 |
++ } |
151 |
++ |
152 |
+ dirfd = local_opendir_nofollow(fs_ctx, dir_path->data); |
153 |
+ if (dirfd == -1) { |
154 |
+ return -1; |
155 |
+@@ -826,6 +855,12 @@ static int local_link(FsContext *ctx, V9fsPath *oldpath, |
156 |
+ int ret = -1; |
157 |
+ int odirfd, ndirfd; |
158 |
+ |
159 |
++ if (ctx->export_flags & V9FS_SM_MAPPED_FILE && |
160 |
++ local_is_mapped_file_metadata(ctx, name)) { |
161 |
++ errno = EINVAL; |
162 |
++ return -1; |
163 |
++ } |
164 |
++ |
165 |
+ odirfd = local_opendir_nofollow(ctx, odirpath); |
166 |
+ if (odirfd == -1) { |
167 |
+ goto out; |
168 |
+@@ -1096,6 +1131,12 @@ static int local_lremovexattr(FsContext *ctx, V9fsPath *fs_path, |
169 |
+ static int local_name_to_path(FsContext *ctx, V9fsPath *dir_path, |
170 |
+ const char *name, V9fsPath *target) |
171 |
+ { |
172 |
++ if (ctx->export_flags & V9FS_SM_MAPPED_FILE && |
173 |
++ local_is_mapped_file_metadata(ctx, name)) { |
174 |
++ errno = EINVAL; |
175 |
++ return -1; |
176 |
++ } |
177 |
++ |
178 |
+ if (dir_path) { |
179 |
+ v9fs_path_sprintf(target, "%s/%s", dir_path->data, name); |
180 |
+ } else if (strcmp(name, "/")) { |
181 |
+@@ -1116,6 +1157,13 @@ static int local_renameat(FsContext *ctx, V9fsPath *olddir, |
182 |
+ int ret; |
183 |
+ int odirfd, ndirfd; |
184 |
+ |
185 |
++ if (ctx->export_flags & V9FS_SM_MAPPED_FILE && |
186 |
++ (local_is_mapped_file_metadata(ctx, old_name) || |
187 |
++ local_is_mapped_file_metadata(ctx, new_name))) { |
188 |
++ errno = EINVAL; |
189 |
++ return -1; |
190 |
++ } |
191 |
++ |
192 |
+ odirfd = local_opendir_nofollow(ctx, olddir->data); |
193 |
+ if (odirfd == -1) { |
194 |
+ return -1; |
195 |
+@@ -1206,6 +1254,12 @@ static int local_unlinkat(FsContext *ctx, V9fsPath *dir, |
196 |
+ int ret; |
197 |
+ int dirfd; |
198 |
+ |
199 |
++ if (ctx->export_flags & V9FS_SM_MAPPED_FILE && |
200 |
++ local_is_mapped_file_metadata(ctx, name)) { |
201 |
++ errno = EINVAL; |
202 |
++ return -1; |
203 |
++ } |
204 |
++ |
205 |
+ dirfd = local_opendir_nofollow(ctx, dir->data); |
206 |
+ if (dirfd == -1) { |
207 |
+ return -1; |
208 |
+-- |
209 |
+2.13.0 |
210 |
+ |
211 |
|
212 |
diff --git a/app-emulation/qemu/files/qemu-2.9.0-CVE-2017-7539.patch b/app-emulation/qemu/files/qemu-2.9.0-CVE-2017-7539.patch |
213 |
deleted file mode 100644 |
214 |
index 3af1697..0000000 |
215 |
--- a/app-emulation/qemu/files/qemu-2.9.0-CVE-2017-7539.patch |
216 |
+++ /dev/null |
217 |
@@ -1,601 +0,0 @@ |
218 |
-From 2b0bbc4f8809c972bad134bc1a2570dbb01dea0b Mon Sep 17 00:00:00 2001 |
219 |
-From: Vladimir Sementsov-Ogievskiy <vsementsov@×××××××××.com> |
220 |
-Date: Fri, 2 Jun 2017 18:01:41 +0300 |
221 |
-Subject: [PATCH] nbd/server: get rid of nbd_negotiate_read and friends |
222 |
- |
223 |
-Functions nbd_negotiate_{read,write,drop_sync} were introduced in |
224 |
-1a6245a5b, when nbd_rwv (was nbd_wr_sync) was working through |
225 |
-qemu_co_sendv_recvv (the path is nbd_wr_sync -> qemu_co_{recv/send} -> |
226 |
-qemu_co_send_recv -> qemu_co_sendv_recvv), which just yields, without |
227 |
-setting any handlers. But starting from ff82911cd nbd_rwv (was |
228 |
-nbd_wr_syncv) works through qio_channel_yield() which sets handlers, so |
229 |
-watchers are redundant in nbd_negotiate_{read,write,drop_sync}, then, |
230 |
-let's just use nbd_{read,write,drop} functions. |
231 |
- |
232 |
-Functions nbd_{read,write,drop} has errp parameter, which is unused in |
233 |
-this patch. This will be fixed later. |
234 |
- |
235 |
-Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@×××××××××.com> |
236 |
-Reviewed-by: Eric Blake <eblake@××××××.com> |
237 |
-Message-Id: <20170602150150.258222-4-vsementsov@×××××××××.com> |
238 |
-Signed-off-by: Paolo Bonzini <pbonzini@××××××.com> |
239 |
---- |
240 |
- nbd/server.c | 107 ++++++++++++----------------------------------------------- |
241 |
- 1 file changed, 22 insertions(+), 85 deletions(-) |
242 |
- |
243 |
-diff --git a/nbd/client.c b/nbd/client.c |
244 |
-index a58fb02..6b74a62 100644 |
245 |
---- a/nbd/client.c |
246 |
-+++ b/nbd/client.c |
247 |
-@@ -86,9 +86,9 @@ static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports); |
248 |
- |
249 |
- */ |
250 |
- |
251 |
--/* Discard length bytes from channel. Return -errno on failure, or |
252 |
-- * the amount of bytes consumed. */ |
253 |
--static ssize_t drop_sync(QIOChannel *ioc, size_t size) |
254 |
-+/* Discard length bytes from channel. Return -errno on failure and 0 on |
255 |
-+ * success*/ |
256 |
-+static int drop_sync(QIOChannel *ioc, size_t size) |
257 |
- { |
258 |
- ssize_t ret = 0; |
259 |
- char small[1024]; |
260 |
-@@ -96,14 +96,13 @@ static ssize_t drop_sync(QIOChannel *ioc, size_t size) |
261 |
- |
262 |
- buffer = sizeof(small) >= size ? small : g_malloc(MIN(65536, size)); |
263 |
- while (size > 0) { |
264 |
-- ssize_t count = read_sync(ioc, buffer, MIN(65536, size)); |
265 |
-+ ssize_t count = MIN(65536, size); |
266 |
-+ ret = read_sync(ioc, buffer, MIN(65536, size)); |
267 |
- |
268 |
-- if (count <= 0) { |
269 |
-+ if (ret < 0) { |
270 |
- goto cleanup; |
271 |
- } |
272 |
-- assert(count <= size); |
273 |
- size -= count; |
274 |
-- ret += count; |
275 |
- } |
276 |
- |
277 |
- cleanup: |
278 |
-@@ -136,12 +135,12 @@ static int nbd_send_option_request(QIOChannel *ioc, uint32_t opt, |
279 |
- stl_be_p(&req.option, opt); |
280 |
- stl_be_p(&req.length, len); |
281 |
- |
282 |
-- if (write_sync(ioc, &req, sizeof(req)) != sizeof(req)) { |
283 |
-+ if (write_sync(ioc, &req, sizeof(req)) < 0) { |
284 |
- error_setg(errp, "Failed to send option request header"); |
285 |
- return -1; |
286 |
- } |
287 |
- |
288 |
-- if (len && write_sync(ioc, (char *) data, len) != len) { |
289 |
-+ if (len && write_sync(ioc, (char *) data, len) < 0) { |
290 |
- error_setg(errp, "Failed to send option request data"); |
291 |
- return -1; |
292 |
- } |
293 |
-@@ -170,7 +169,7 @@ static int nbd_receive_option_reply(QIOChannel *ioc, uint32_t opt, |
294 |
- nbd_opt_reply *reply, Error **errp) |
295 |
- { |
296 |
- QEMU_BUILD_BUG_ON(sizeof(*reply) != 20); |
297 |
-- if (read_sync(ioc, reply, sizeof(*reply)) != sizeof(*reply)) { |
298 |
-+ if (read_sync(ioc, reply, sizeof(*reply)) < 0) { |
299 |
- error_setg(errp, "failed to read option reply"); |
300 |
- nbd_send_opt_abort(ioc); |
301 |
- return -1; |
302 |
-@@ -219,7 +218,7 @@ static int nbd_handle_reply_err(QIOChannel *ioc, nbd_opt_reply *reply, |
303 |
- goto cleanup; |
304 |
- } |
305 |
- msg = g_malloc(reply->length + 1); |
306 |
-- if (read_sync(ioc, msg, reply->length) != reply->length) { |
307 |
-+ if (read_sync(ioc, msg, reply->length) < 0) { |
308 |
- error_setg(errp, "failed to read option error message"); |
309 |
- goto cleanup; |
310 |
- } |
311 |
-@@ -321,7 +320,7 @@ static int nbd_receive_list(QIOChannel *ioc, const char *want, bool *match, |
312 |
- nbd_send_opt_abort(ioc); |
313 |
- return -1; |
314 |
- } |
315 |
-- if (read_sync(ioc, &namelen, sizeof(namelen)) != sizeof(namelen)) { |
316 |
-+ if (read_sync(ioc, &namelen, sizeof(namelen)) < 0) { |
317 |
- error_setg(errp, "failed to read option name length"); |
318 |
- nbd_send_opt_abort(ioc); |
319 |
- return -1; |
320 |
-@@ -334,7 +333,7 @@ static int nbd_receive_list(QIOChannel *ioc, const char *want, bool *match, |
321 |
- return -1; |
322 |
- } |
323 |
- if (namelen != strlen(want)) { |
324 |
-- if (drop_sync(ioc, len) != len) { |
325 |
-+ if (drop_sync(ioc, len) < 0) { |
326 |
- error_setg(errp, "failed to skip export name with wrong length"); |
327 |
- nbd_send_opt_abort(ioc); |
328 |
- return -1; |
329 |
-@@ -343,14 +342,14 @@ static int nbd_receive_list(QIOChannel *ioc, const char *want, bool *match, |
330 |
- } |
331 |
- |
332 |
- assert(namelen < sizeof(name)); |
333 |
-- if (read_sync(ioc, name, namelen) != namelen) { |
334 |
-+ if (read_sync(ioc, name, namelen) < 0) { |
335 |
- error_setg(errp, "failed to read export name"); |
336 |
- nbd_send_opt_abort(ioc); |
337 |
- return -1; |
338 |
- } |
339 |
- name[namelen] = '\0'; |
340 |
- len -= namelen; |
341 |
-- if (drop_sync(ioc, len) != len) { |
342 |
-+ if (drop_sync(ioc, len) < 0) { |
343 |
- error_setg(errp, "failed to read export description"); |
344 |
- nbd_send_opt_abort(ioc); |
345 |
- return -1; |
346 |
-@@ -477,7 +476,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, |
347 |
- goto fail; |
348 |
- } |
349 |
- |
350 |
-- if (read_sync(ioc, buf, 8) != 8) { |
351 |
-+ if (read_sync(ioc, buf, 8) < 0) { |
352 |
- error_setg(errp, "Failed to read data"); |
353 |
- goto fail; |
354 |
- } |
355 |
-@@ -503,7 +502,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, |
356 |
- goto fail; |
357 |
- } |
358 |
- |
359 |
-- if (read_sync(ioc, &magic, sizeof(magic)) != sizeof(magic)) { |
360 |
-+ if (read_sync(ioc, &magic, sizeof(magic)) < 0) { |
361 |
- error_setg(errp, "Failed to read magic"); |
362 |
- goto fail; |
363 |
- } |
364 |
-@@ -515,8 +514,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, |
365 |
- uint16_t globalflags; |
366 |
- bool fixedNewStyle = false; |
367 |
- |
368 |
-- if (read_sync(ioc, &globalflags, sizeof(globalflags)) != |
369 |
-- sizeof(globalflags)) { |
370 |
-+ if (read_sync(ioc, &globalflags, sizeof(globalflags)) < 0) { |
371 |
- error_setg(errp, "Failed to read server flags"); |
372 |
- goto fail; |
373 |
- } |
374 |
-@@ -534,8 +532,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, |
375 |
- } |
376 |
- /* client requested flags */ |
377 |
- clientflags = cpu_to_be32(clientflags); |
378 |
-- if (write_sync(ioc, &clientflags, sizeof(clientflags)) != |
379 |
-- sizeof(clientflags)) { |
380 |
-+ if (write_sync(ioc, &clientflags, sizeof(clientflags)) < 0) { |
381 |
- error_setg(errp, "Failed to send clientflags field"); |
382 |
- goto fail; |
383 |
- } |
384 |
-@@ -573,13 +570,13 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, |
385 |
- } |
386 |
- |
387 |
- /* Read the response */ |
388 |
-- if (read_sync(ioc, &s, sizeof(s)) != sizeof(s)) { |
389 |
-+ if (read_sync(ioc, &s, sizeof(s)) < 0) { |
390 |
- error_setg(errp, "Failed to read export length"); |
391 |
- goto fail; |
392 |
- } |
393 |
- *size = be64_to_cpu(s); |
394 |
- |
395 |
-- if (read_sync(ioc, flags, sizeof(*flags)) != sizeof(*flags)) { |
396 |
-+ if (read_sync(ioc, flags, sizeof(*flags)) < 0) { |
397 |
- error_setg(errp, "Failed to read export flags"); |
398 |
- goto fail; |
399 |
- } |
400 |
-@@ -596,14 +593,14 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, |
401 |
- goto fail; |
402 |
- } |
403 |
- |
404 |
-- if (read_sync(ioc, &s, sizeof(s)) != sizeof(s)) { |
405 |
-+ if (read_sync(ioc, &s, sizeof(s)) < 0) { |
406 |
- error_setg(errp, "Failed to read export length"); |
407 |
- goto fail; |
408 |
- } |
409 |
- *size = be64_to_cpu(s); |
410 |
- TRACE("Size is %" PRIu64, *size); |
411 |
- |
412 |
-- if (read_sync(ioc, &oldflags, sizeof(oldflags)) != sizeof(oldflags)) { |
413 |
-+ if (read_sync(ioc, &oldflags, sizeof(oldflags)) < 0) { |
414 |
- error_setg(errp, "Failed to read export flags"); |
415 |
- goto fail; |
416 |
- } |
417 |
-@@ -619,7 +616,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, |
418 |
- } |
419 |
- |
420 |
- TRACE("Size is %" PRIu64 ", export flags %" PRIx16, *size, *flags); |
421 |
-- if (zeroes && drop_sync(ioc, 124) != 124) { |
422 |
-+ if (zeroes && drop_sync(ioc, 124) < 0) { |
423 |
- error_setg(errp, "Failed to read reserved block"); |
424 |
- goto fail; |
425 |
- } |
426 |
-@@ -744,7 +741,6 @@ int nbd_disconnect(int fd) |
427 |
- ssize_t nbd_send_request(QIOChannel *ioc, NBDRequest *request) |
428 |
- { |
429 |
- uint8_t buf[NBD_REQUEST_SIZE]; |
430 |
-- ssize_t ret; |
431 |
- |
432 |
- TRACE("Sending request to server: " |
433 |
- "{ .from = %" PRIu64", .len = %" PRIu32 ", .handle = %" PRIu64 |
434 |
-@@ -759,16 +755,7 @@ ssize_t nbd_send_request(QIOChannel *ioc, NBDRequest *request) |
435 |
- stq_be_p(buf + 16, request->from); |
436 |
- stl_be_p(buf + 24, request->len); |
437 |
- |
438 |
-- ret = write_sync(ioc, buf, sizeof(buf)); |
439 |
-- if (ret < 0) { |
440 |
-- return ret; |
441 |
-- } |
442 |
-- |
443 |
-- if (ret != sizeof(buf)) { |
444 |
-- LOG("writing to socket failed"); |
445 |
-- return -EINVAL; |
446 |
-- } |
447 |
-- return 0; |
448 |
-+ return write_sync(ioc, buf, sizeof(buf)); |
449 |
- } |
450 |
- |
451 |
- ssize_t nbd_receive_reply(QIOChannel *ioc, NBDReply *reply) |
452 |
-@@ -777,7 +764,7 @@ ssize_t nbd_receive_reply(QIOChannel *ioc, NBDReply *reply) |
453 |
- uint32_t magic; |
454 |
- ssize_t ret; |
455 |
- |
456 |
-- ret = read_sync(ioc, buf, sizeof(buf)); |
457 |
-+ ret = read_sync_eof(ioc, buf, sizeof(buf)); |
458 |
- if (ret <= 0) { |
459 |
- return ret; |
460 |
- } |
461 |
-diff --git a/nbd/nbd-internal.h b/nbd/nbd-internal.h |
462 |
-index f43d990..e6bbc7c 100644 |
463 |
---- a/nbd/nbd-internal.h |
464 |
-+++ b/nbd/nbd-internal.h |
465 |
-@@ -94,7 +94,13 @@ |
466 |
- #define NBD_ENOSPC 28 |
467 |
- #define NBD_ESHUTDOWN 108 |
468 |
- |
469 |
--static inline ssize_t read_sync(QIOChannel *ioc, void *buffer, size_t size) |
470 |
-+/* read_sync_eof |
471 |
-+ * Tries to read @size bytes from @ioc. Returns number of bytes actually read. |
472 |
-+ * May return a value >= 0 and < size only on EOF, i.e. when iteratively called |
473 |
-+ * qio_channel_readv() returns 0. So, there are no needs to call read_sync_eof |
474 |
-+ * iteratively. |
475 |
-+ */ |
476 |
-+static inline ssize_t read_sync_eof(QIOChannel *ioc, void *buffer, size_t size) |
477 |
- { |
478 |
- struct iovec iov = { .iov_base = buffer, .iov_len = size }; |
479 |
- /* Sockets are kept in blocking mode in the negotiation phase. After |
480 |
-@@ -105,12 +111,32 @@ static inline ssize_t read_sync(QIOChannel *ioc, void *buffer, size_t size) |
481 |
- return nbd_wr_syncv(ioc, &iov, 1, size, true); |
482 |
- } |
483 |
- |
484 |
--static inline ssize_t write_sync(QIOChannel *ioc, const void *buffer, |
485 |
-- size_t size) |
486 |
-+/* read_sync |
487 |
-+ * Reads @size bytes from @ioc. Returns 0 on success. |
488 |
-+ */ |
489 |
-+static inline int read_sync(QIOChannel *ioc, void *buffer, size_t size) |
490 |
-+{ |
491 |
-+ ssize_t ret = read_sync_eof(ioc, buffer, size); |
492 |
-+ |
493 |
-+ if (ret >= 0 && ret != size) { |
494 |
-+ ret = -EINVAL; |
495 |
-+ } |
496 |
-+ |
497 |
-+ return ret < 0 ? ret : 0; |
498 |
-+} |
499 |
-+ |
500 |
-+/* write_sync |
501 |
-+ * Writes @size bytes to @ioc. Returns 0 on success. |
502 |
-+ */ |
503 |
-+static inline int write_sync(QIOChannel *ioc, const void *buffer, size_t size) |
504 |
- { |
505 |
- struct iovec iov = { .iov_base = (void *) buffer, .iov_len = size }; |
506 |
- |
507 |
-- return nbd_wr_syncv(ioc, &iov, 1, size, false); |
508 |
-+ ssize_t ret = nbd_wr_syncv(ioc, &iov, 1, size, false); |
509 |
-+ |
510 |
-+ assert(ret < 0 || ret == size); |
511 |
-+ |
512 |
-+ return ret < 0 ? ret : 0; |
513 |
- } |
514 |
- |
515 |
- struct NBDTLSHandshakeData { |
516 |
-diff --git a/nbd/server.c b/nbd/server.c |
517 |
-index 924a1fe..a1f106b 100644 |
518 |
---- a/nbd/server.c |
519 |
-+++ b/nbd/server.c |
520 |
-@@ -104,69 +104,6 @@ struct NBDClient { |
521 |
- |
522 |
- static void nbd_client_receive_next_request(NBDClient *client); |
523 |
- |
524 |
--static gboolean nbd_negotiate_continue(QIOChannel *ioc, |
525 |
-- GIOCondition condition, |
526 |
-- void *opaque) |
527 |
--{ |
528 |
-- qemu_coroutine_enter(opaque); |
529 |
-- return TRUE; |
530 |
--} |
531 |
-- |
532 |
--static ssize_t nbd_negotiate_read(QIOChannel *ioc, void *buffer, size_t size) |
533 |
--{ |
534 |
-- ssize_t ret; |
535 |
-- guint watch; |
536 |
-- |
537 |
-- assert(qemu_in_coroutine()); |
538 |
-- /* Negotiation are always in main loop. */ |
539 |
-- watch = qio_channel_add_watch(ioc, |
540 |
-- G_IO_IN, |
541 |
-- nbd_negotiate_continue, |
542 |
-- qemu_coroutine_self(), |
543 |
-- NULL); |
544 |
-- ret = read_sync(ioc, buffer, size); |
545 |
-- g_source_remove(watch); |
546 |
-- return ret; |
547 |
-- |
548 |
--} |
549 |
-- |
550 |
--static ssize_t nbd_negotiate_write(QIOChannel *ioc, const void *buffer, |
551 |
-- size_t size) |
552 |
--{ |
553 |
-- ssize_t ret; |
554 |
-- guint watch; |
555 |
-- |
556 |
-- assert(qemu_in_coroutine()); |
557 |
-- /* Negotiation are always in main loop. */ |
558 |
-- watch = qio_channel_add_watch(ioc, |
559 |
-- G_IO_OUT, |
560 |
-- nbd_negotiate_continue, |
561 |
-- qemu_coroutine_self(), |
562 |
-- NULL); |
563 |
-- ret = write_sync(ioc, buffer, size); |
564 |
-- g_source_remove(watch); |
565 |
-- return ret; |
566 |
--} |
567 |
-- |
568 |
--static ssize_t nbd_negotiate_drop_sync(QIOChannel *ioc, size_t size) |
569 |
--{ |
570 |
-- ssize_t ret, dropped = size; |
571 |
-- uint8_t *buffer = g_malloc(MIN(65536, size)); |
572 |
-- |
573 |
-- while (size > 0) { |
574 |
-- ret = nbd_negotiate_read(ioc, buffer, MIN(65536, size)); |
575 |
-- if (ret < 0) { |
576 |
-- g_free(buffer); |
577 |
-- return ret; |
578 |
-- } |
579 |
-- |
580 |
-- assert(ret <= size); |
581 |
-- size -= ret; |
582 |
-- } |
583 |
-- |
584 |
-- g_free(buffer); |
585 |
-- return dropped; |
586 |
--} |
587 |
- |
588 |
- /* Basic flow for negotiation |
589 |
- |
590 |
-@@ -206,22 +143,22 @@ static int nbd_negotiate_send_rep_len(QIOChannel *ioc, uint32_t type, |
591 |
- type, opt, len); |
592 |
- |
593 |
- magic = cpu_to_be64(NBD_REP_MAGIC); |
594 |
-- if (nbd_negotiate_write(ioc, &magic, sizeof(magic)) != sizeof(magic)) { |
595 |
-+ if (nbd_write(ioc, &magic, sizeof(magic), NULL) < 0) { |
596 |
- LOG("write failed (rep magic)"); |
597 |
- return -EINVAL; |
598 |
- } |
599 |
- opt = cpu_to_be32(opt); |
600 |
-- if (nbd_negotiate_write(ioc, &opt, sizeof(opt)) != sizeof(opt)) { |
601 |
-+ if (nbd_write(ioc, &opt, sizeof(opt), NULL) < 0) { |
602 |
- LOG("write failed (rep opt)"); |
603 |
- return -EINVAL; |
604 |
- } |
605 |
- type = cpu_to_be32(type); |
606 |
-- if (nbd_negotiate_write(ioc, &type, sizeof(type)) != sizeof(type)) { |
607 |
-+ if (nbd_write(ioc, &type, sizeof(type), NULL) < 0) { |
608 |
- LOG("write failed (rep type)"); |
609 |
- return -EINVAL; |
610 |
- } |
611 |
- len = cpu_to_be32(len); |
612 |
-- if (nbd_negotiate_write(ioc, &len, sizeof(len)) != sizeof(len)) { |
613 |
-+ if (nbd_write(ioc, &len, sizeof(len), NULL) < 0) { |
614 |
- LOG("write failed (rep data length)"); |
615 |
- return -EINVAL; |
616 |
- } |
617 |
-@@ -256,7 +193,7 @@ nbd_negotiate_send_rep_err(QIOChannel *ioc, uint32_t type, |
618 |
- if (ret < 0) { |
619 |
- goto out; |
620 |
- } |
621 |
-- if (nbd_negotiate_write(ioc, msg, len) != len) { |
622 |
-+ if (nbd_write(ioc, msg, len, NULL) < 0) { |
623 |
- LOG("write failed (error message)"); |
624 |
- ret = -EIO; |
625 |
- } else { |
626 |
-@@ -287,15 +224,15 @@ static int nbd_negotiate_send_rep_list(QIOChannel *ioc, NBDExport *exp) |
627 |
- } |
628 |
- |
629 |
- len = cpu_to_be32(name_len); |
630 |
-- if (nbd_negotiate_write(ioc, &len, sizeof(len)) != sizeof(len)) { |
631 |
-+ if (nbd_write(ioc, &len, sizeof(len), NULL) < 0) { |
632 |
- LOG("write failed (name length)"); |
633 |
- return -EINVAL; |
634 |
- } |
635 |
-- if (nbd_negotiate_write(ioc, name, name_len) != name_len) { |
636 |
-+ if (nbd_write(ioc, name, name_len, NULL) < 0) { |
637 |
- LOG("write failed (name buffer)"); |
638 |
- return -EINVAL; |
639 |
- } |
640 |
-- if (nbd_negotiate_write(ioc, desc, desc_len) != desc_len) { |
641 |
-+ if (nbd_write(ioc, desc, desc_len, NULL) < 0) { |
642 |
- LOG("write failed (description buffer)"); |
643 |
- return -EINVAL; |
644 |
- } |
645 |
-@@ -309,7 +246,7 @@ static int nbd_negotiate_handle_list(NBDClient *client, uint32_t length) |
646 |
- NBDExport *exp; |
647 |
- |
648 |
- if (length) { |
649 |
-- if (nbd_negotiate_drop_sync(client->ioc, length) != length) { |
650 |
-+ if (nbd_drop(client->ioc, length, NULL) < 0) { |
651 |
- return -EIO; |
652 |
- } |
653 |
- return nbd_negotiate_send_rep_err(client->ioc, |
654 |
-@@ -340,7 +277,7 @@ static int nbd_negotiate_handle_export_name(NBDClient *client, uint32_t length) |
655 |
- LOG("Bad length received"); |
656 |
- goto fail; |
657 |
- } |
658 |
-- if (nbd_negotiate_read(client->ioc, name, length) != length) { |
659 |
-+ if (nbd_read(client->ioc, name, length, NULL) < 0) { |
660 |
- LOG("read failed"); |
661 |
- goto fail; |
662 |
- } |
663 |
-@@ -373,7 +310,7 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client, |
664 |
- TRACE("Setting up TLS"); |
665 |
- ioc = client->ioc; |
666 |
- if (length) { |
667 |
-- if (nbd_negotiate_drop_sync(ioc, length) != length) { |
668 |
-+ if (nbd_drop(ioc, length, NULL) < 0) { |
669 |
- return NULL; |
670 |
- } |
671 |
- nbd_negotiate_send_rep_err(ioc, NBD_REP_ERR_INVALID, NBD_OPT_STARTTLS, |
672 |
-@@ -437,8 +374,7 @@ static int nbd_negotiate_options(NBDClient *client) |
673 |
- ... Rest of request |
674 |
- */ |
675 |
- |
676 |
-- if (nbd_negotiate_read(client->ioc, &flags, sizeof(flags)) != |
677 |
-- sizeof(flags)) { |
678 |
-+ if (nbd_read(client->ioc, &flags, sizeof(flags), NULL) < 0) { |
679 |
- LOG("read failed"); |
680 |
- return -EIO; |
681 |
- } |
682 |
-@@ -464,8 +400,7 @@ static int nbd_negotiate_options(NBDClient *client) |
683 |
- uint32_t clientflags, length; |
684 |
- uint64_t magic; |
685 |
- |
686 |
-- if (nbd_negotiate_read(client->ioc, &magic, sizeof(magic)) != |
687 |
-- sizeof(magic)) { |
688 |
-+ if (nbd_read(client->ioc, &magic, sizeof(magic), NULL) < 0) { |
689 |
- LOG("read failed"); |
690 |
- return -EINVAL; |
691 |
- } |
692 |
-@@ -475,15 +410,15 @@ static int nbd_negotiate_options(NBDClient *client) |
693 |
- return -EINVAL; |
694 |
- } |
695 |
- |
696 |
-- if (nbd_negotiate_read(client->ioc, &clientflags, |
697 |
-- sizeof(clientflags)) != sizeof(clientflags)) { |
698 |
-+ if (nbd_read(client->ioc, &clientflags, |
699 |
-+ sizeof(clientflags), NULL) < 0) |
700 |
-+ { |
701 |
- LOG("read failed"); |
702 |
- return -EINVAL; |
703 |
- } |
704 |
- clientflags = be32_to_cpu(clientflags); |
705 |
- |
706 |
-- if (nbd_negotiate_read(client->ioc, &length, sizeof(length)) != |
707 |
-- sizeof(length)) { |
708 |
-+ if (nbd_read(client->ioc, &length, sizeof(length), NULL) < 0) { |
709 |
- LOG("read failed"); |
710 |
- return -EINVAL; |
711 |
- } |
712 |
-@@ -513,7 +448,7 @@ static int nbd_negotiate_options(NBDClient *client) |
713 |
- return -EINVAL; |
714 |
- |
715 |
- default: |
716 |
-- if (nbd_negotiate_drop_sync(client->ioc, length) != length) { |
717 |
-+ if (nbd_drop(client->ioc, length, NULL) < 0) { |
718 |
- return -EIO; |
719 |
- } |
720 |
- ret = nbd_negotiate_send_rep_err(client->ioc, |
721 |
-@@ -551,7 +486,7 @@ static int nbd_negotiate_options(NBDClient *client) |
722 |
- return nbd_negotiate_handle_export_name(client, length); |
723 |
- |
724 |
- case NBD_OPT_STARTTLS: |
725 |
-- if (nbd_negotiate_drop_sync(client->ioc, length) != length) { |
726 |
-+ if (nbd_drop(client->ioc, length, NULL) < 0) { |
727 |
- return -EIO; |
728 |
- } |
729 |
- if (client->tlscreds) { |
730 |
-@@ -570,7 +505,7 @@ static int nbd_negotiate_options(NBDClient *client) |
731 |
- } |
732 |
- break; |
733 |
- default: |
734 |
-- if (nbd_negotiate_drop_sync(client->ioc, length) != length) { |
735 |
-+ if (nbd_drop(client->ioc, length, NULL) < 0) { |
736 |
- return -EIO; |
737 |
- } |
738 |
- ret = nbd_negotiate_send_rep_err(client->ioc, |
739 |
-@@ -659,12 +594,12 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data) |
740 |
- TRACE("TLS cannot be enabled with oldstyle protocol"); |
741 |
- goto fail; |
742 |
- } |
743 |
-- if (nbd_negotiate_write(client->ioc, buf, sizeof(buf)) != sizeof(buf)) { |
744 |
-+ if (nbd_write(client->ioc, buf, sizeof(buf), NULL) < 0) { |
745 |
- LOG("write failed"); |
746 |
- goto fail; |
747 |
- } |
748 |
- } else { |
749 |
-- if (nbd_negotiate_write(client->ioc, buf, 18) != 18) { |
750 |
-+ if (nbd_write(client->ioc, buf, 18, NULL) < 0) { |
751 |
- LOG("write failed"); |
752 |
- goto fail; |
753 |
- } |
754 |
-@@ -679,7 +614,7 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data) |
755 |
- stq_be_p(buf + 18, client->exp->size); |
756 |
- stw_be_p(buf + 26, client->exp->nbdflags | myflags); |
757 |
- len = client->no_zeroes ? 10 : sizeof(buf) - 18; |
758 |
-- if (nbd_negotiate_write(client->ioc, buf + 18, len) != len) { |
759 |
-+ if (nbd_write(client->ioc, buf + 18, len, NULL) < 0) { |
760 |
- LOG("write failed"); |
761 |
- goto fail; |
762 |
- } |
763 |
-@@ -702,11 +637,6 @@ static ssize_t nbd_receive_request(QIOChannel *ioc, NBDRequest *request) |
764 |
- return ret; |
765 |
- } |
766 |
- |
767 |
-- if (ret != sizeof(buf)) { |
768 |
-- LOG("read failed"); |
769 |
-- return -EINVAL; |
770 |
-- } |
771 |
-- |
772 |
- /* Request |
773 |
- [ 0 .. 3] magic (NBD_REQUEST_MAGIC) |
774 |
- [ 4 .. 5] flags (NBD_CMD_FLAG_FUA, ...) |
775 |
-@@ -737,7 +667,6 @@ static ssize_t nbd_receive_request(QIOChannel *ioc, NBDRequest *request) |
776 |
- static ssize_t nbd_send_reply(QIOChannel *ioc, NBDReply *reply) |
777 |
- { |
778 |
- uint8_t buf[NBD_REPLY_SIZE]; |
779 |
-- ssize_t ret; |
780 |
- |
781 |
- reply->error = system_errno_to_nbd_errno(reply->error); |
782 |
- |
783 |
-@@ -754,16 +683,7 @@ static ssize_t nbd_send_reply(QIOChannel *ioc, NBDReply *reply) |
784 |
- stl_be_p(buf + 4, reply->error); |
785 |
- stq_be_p(buf + 8, reply->handle); |
786 |
- |
787 |
-- ret = write_sync(ioc, buf, sizeof(buf)); |
788 |
-- if (ret < 0) { |
789 |
-- return ret; |
790 |
-- } |
791 |
-- |
792 |
-- if (ret != sizeof(buf)) { |
793 |
-- LOG("writing to socket failed"); |
794 |
-- return -EINVAL; |
795 |
-- } |
796 |
-- return 0; |
797 |
-+ return write_sync(ioc, buf, sizeof(buf)); |
798 |
- } |
799 |
- |
800 |
- #define MAX_NBD_REQUESTS 16 |
801 |
-@@ -1067,7 +987,7 @@ static ssize_t nbd_co_send_reply(NBDRequestData *req, NBDReply *reply, |
802 |
- rc = nbd_send_reply(client->ioc, reply); |
803 |
- if (rc >= 0) { |
804 |
- ret = write_sync(client->ioc, req->data, len); |
805 |
-- if (ret != len) { |
806 |
-+ if (ret < 0) { |
807 |
- rc = -EIO; |
808 |
- } |
809 |
- } |
810 |
-@@ -1141,7 +1061,7 @@ static ssize_t nbd_co_receive_request(NBDRequestData *req, |
811 |
- if (request->type == NBD_CMD_WRITE) { |
812 |
- TRACE("Reading %" PRIu32 " byte(s)", request->len); |
813 |
- |
814 |
-- if (read_sync(client->ioc, req->data, request->len) != request->len) { |
815 |
-+ if (read_sync(client->ioc, req->data, request->len) < 0) { |
816 |
- LOG("reading from socket failed"); |
817 |
- rc = -EIO; |
818 |
- goto out; |