commit:     9212f510625a88c624d5d8d9456842091ee93305
Author:     Aric Belsito <lluixhi <AT> gmail <DOT> com>
AuthorDate: Thu Jul 27 17:59:01 2017 +0000
Commit:     Aric Belsito <lluixhi <AT> gmail <DOT> com>
CommitDate: Thu Jul 27 17:59:01 2017 +0000
URL:        https://gitweb.gentoo.org/proj/musl.git/commit/?id=9212f510

app-emulation/qemu: restore patch

deleted the wrong one..

 app-emulation/qemu/Manifest                        |   2 +-
 .../qemu/files/qemu-2.9.0-CVE-2017-7493.patch      | 174 ++++++
 .../qemu/files/qemu-2.9.0-CVE-2017-7539.patch      | 601 ---------------------
 3 files changed, 175 insertions(+), 602 deletions(-)

diff --git a/app-emulation/qemu/Manifest b/app-emulation/qemu/Manifest
index e4a3f79..e3f4bd2 100644
--- a/app-emulation/qemu/Manifest
+++ b/app-emulation/qemu/Manifest
@@ -9,7 +9,7 @@ AUX qemu-2.9.0-CVE-2017-10664.patch 1613 SHA256 
5941cc41f0c02b185be3f6ba450f155d
 AUX qemu-2.9.0-CVE-2017-10806.patch 1450 SHA256 
ef884e2ed3adb618273af1d036ed0c7e3a09599e3d042080bb4b5014c6bc54d7 SHA512 
38fea2c1a2a5a224585a07a028a8c4cfc1bec4d943e85c13e01228062bf306a502b0948270863b226bc974832e3af18158904fbfc08ccdf1f72f06e7830780d5
 WHIRLPOOL 
f02fb957016af684dc894f93ec0b7dcca3febb8d37882aae1e17d2aca9948e200a013ae467cb54c5555e76c73f124a37c95fde189a4492d88322802d8160310c
 AUX qemu-2.9.0-CVE-2017-11334.patch 1362 SHA256 
bc2f3a50ad174e5453d0e4d1e14e9723b316e2339dc25ff31e27060ee13242bb SHA512 
422296269ec29b3313c984947ac48b7179ce8e169131624d316589a621778f846b883e76cdfba50c62dc63ab5fede0ad0292704c1ca1cc9e1e7b3b01a153b8c8
 WHIRLPOOL 
504cf6b2ebfb11bf1471f920d101df28df59f1a585eac31ac278a366f2b769386bc7d100aa8386b3f8f45d5f5f700aa6625be3192eb4f1f3b77e69c6684cf74f
 AUX qemu-2.9.0-CVE-2017-11434.patch 912 SHA256 
e8be3cb9261f8735ff2a50fb8b79ccfea85456c7a2e5a5702fcc5339463dc05a SHA512 
db95d9459b9669e0981195fe15f16c4e74d5f00c03e1ce5e33541e005260e77fa114b1b3f30bc06d80b723a6361b704fb58709b25773c168c8aa8f5f96580ac9
 WHIRLPOOL 
c68e25024ab3c1d01e5b53d0a7b1591110b96d78079bc940ec28da2e2770dac6b1f9bbaaeb97c88ea0e1b46db886f7035d81bde582750e560d136916ecdab8a2
-AUX qemu-2.9.0-CVE-2017-7539.patch 22018 SHA256 
523d41e08a2aab888e3e63b4dda6a19e535fe6fba2bf08b6ead06498ca923f29 SHA512 
5c81488aeae78307bee551a3a037f3b9cf55971a17c5df17f89f31224bdfa0a5e79141341314546256bffe542b781ad25151c54340a63c766086a578e5465825
 WHIRLPOOL 
085fc7e7d40c803a3caf15cdee77ce553b385919678ecf4bbcc3f532af5e482ca804a167af43e4f393da93aed88285690d84a3054c7f0df61d603d0046029dbc
+AUX qemu-2.9.0-CVE-2017-7493.patch 5656 SHA256 
77462d39e811e58d3761523a6c580485bdfca0e74adbd10cf24c254e0ece262a SHA512 
2b01f2878c98e77997b645ba80e69b5db398ef1e8f2b66344818d3c9af35dd66d49041ef9ee8aa152bf3e94970b4db282cf53909cb13b2532bc0a104251b2e81
 WHIRLPOOL 
23c788c5a78e126a61bd277e9fa1511cc71b8fbdc83a5bf319c5fc424219cbcceefad737844e45c11a76e047f8a49853d0a85b267f24f7b23bb7276d0edf0451
 AUX qemu-2.9.0-CVE-2017-8112.patch 696 SHA256 
a4dcc2a94749a5c20ef38d4c7ce13cd1ffe46017c77eea29ced0bec5c232e6aa SHA512 
840f5270332729e0149a4705bae5fcc16e9503a995d6bfa5033904a544add337ca8ccb1d2a36bb57cc198f6354f5253403f1c4f04cbd18c08b4e1a9d6af9e07f
 WHIRLPOOL 
1ba4e75fdd0c767254c85754612da9e8ff9ba2e7ea0811f723844bec190946805cd59db83f347a3dea4296d2b58d2df4a8d99a492335ba818824348bcebdd556
 AUX qemu-2.9.0-CVE-2017-8309.patch 595 SHA256 
8231747fe4d9c97392fe44b117caccd07d320313dc27fad17ac658122113ced9 SHA512 
4415c36acb4f0594de7fe0de2b669d03d6b54ae44eb7f1f285c36223a02cca887b57db27a43ab1cc2e7e193ee5bce2748f9d2056aa925e0cc8f2133e67168a74
 WHIRLPOOL 
af4c5e9763a0e114e554a1c8be99ea79da0b634fdc9d87922c7713187f1f904bfcce103648d549bbb190e92443664dbb9bd7592d8137f2337be0f4b22d1f9bd1
 AUX qemu-2.9.0-CVE-2017-8379.patch 2736 SHA256 
f2f8910c8e1ce9fc9804f4fbbe978fee20ccbfccc5efe49f42cdaafa63c511ce SHA512 
79e32f75d98ca4a92a5069b65c5b9cff16064255ed4d161e4e292b97373742c25d5ddc12dfffa627197fdb5e0808108b30d0182a9c060cd181723bd90c618d15
 WHIRLPOOL 
545c00189da3b252c80bb35c6b6d3368a02b36b06f2866838ddd9ebb9ccf2b608ae278ee192b6b3aef2966736afe9bcdd646c80c228ec5daef76b92bd2721bd5

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
new file mode 100644
index 0000000..346e771
--- /dev/null
+++ b/app-emulation/qemu/files/qemu-2.9.0-CVE-2017-7493.patch
@@ -0,0 +1,174 @@
+From 7a95434e0ca8a037fd8aa1a2e2461f92585eb77b Mon Sep 17 00:00:00 2001
+From: Greg Kurz <[email protected]>
+Date: Fri, 5 May 2017 14:48:08 +0200
+Subject: [PATCH] 9pfs: local: forbid client access to metadata (CVE-2017-7493)
+
+When using the mapped-file security mode, we shouldn't let the client mess
+with the metadata. The current code already tries to hide the metadata dir
+from the client by skipping it in local_readdir(). But the client can still
+access or modify it through several other operations. This can be used to
+escalate privileges in the guest.
+
+Affected backend operations are:
+- local_mknod()
+- local_mkdir()
+- local_open2()
+- local_symlink()
+- local_link()
+- local_unlinkat()
+- local_renameat()
+- local_rename()
+- local_name_to_path()
+
+Other operations are safe because they are only passed a fid path, which
+is computed internally in local_name_to_path().
+
+This patch converts all the functions listed above to fail and return
+EINVAL when being passed the name of the metadata dir. This may look
+like a poor choice for errno, but there's no such thing as an illegal
+path name on Linux and I could not think of anything better.
+
+This fixes CVE-2017-7493.
+
+Reported-by: Leo Gaspard <[email protected]>
+Signed-off-by: Greg Kurz <[email protected]>
+Reviewed-by: Eric Blake <[email protected]>
+---
+ hw/9pfs/9p-local.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 56 insertions(+), 2 deletions(-)
+
+diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
+index f3ebca4f7a..a2486566af 100644
+--- a/hw/9pfs/9p-local.c
++++ b/hw/9pfs/9p-local.c
+@@ -452,6 +452,11 @@ static off_t local_telldir(FsContext *ctx, 
V9fsFidOpenState *fs)
+     return telldir(fs->dir.stream);
+ }
+ 
++static bool local_is_mapped_file_metadata(FsContext *fs_ctx, const char *name)
++{
++    return !strcmp(name, VIRTFS_META_DIR);
++}
++
+ static struct dirent *local_readdir(FsContext *ctx, V9fsFidOpenState *fs)
+ {
+     struct dirent *entry;
+@@ -465,8 +470,8 @@ again:
+     if (ctx->export_flags & V9FS_SM_MAPPED) {
+         entry->d_type = DT_UNKNOWN;
+     } else if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
+-        if (!strcmp(entry->d_name, VIRTFS_META_DIR)) {
+-            /* skp the meta data directory */
++        if (local_is_mapped_file_metadata(ctx, entry->d_name)) {
++            /* skip the meta data directory */
+             goto again;
+         }
+         entry->d_type = DT_UNKNOWN;
+@@ -559,6 +564,12 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath 
*dir_path,
+     int err = -1;
+     int dirfd;
+ 
++    if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE &&
++        local_is_mapped_file_metadata(fs_ctx, name)) {
++        errno = EINVAL;
++        return -1;
++    }
++
+     dirfd = local_opendir_nofollow(fs_ctx, dir_path->data);
+     if (dirfd == -1) {
+         return -1;
+@@ -605,6 +616,12 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath 
*dir_path,
+     int err = -1;
+     int dirfd;
+ 
++    if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE &&
++        local_is_mapped_file_metadata(fs_ctx, name)) {
++        errno = EINVAL;
++        return -1;
++    }
++
+     dirfd = local_opendir_nofollow(fs_ctx, dir_path->data);
+     if (dirfd == -1) {
+         return -1;
+@@ -694,6 +711,12 @@ static int local_open2(FsContext *fs_ctx, V9fsPath 
*dir_path, const char *name,
+     int err = -1;
+     int dirfd;
+ 
++    if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE &&
++        local_is_mapped_file_metadata(fs_ctx, name)) {
++        errno = EINVAL;
++        return -1;
++    }
++
+     /*
+      * Mark all the open to not follow symlinks
+      */
+@@ -752,6 +775,12 @@ static int local_symlink(FsContext *fs_ctx, const char 
*oldpath,
+     int err = -1;
+     int dirfd;
+ 
++    if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE &&
++        local_is_mapped_file_metadata(fs_ctx, name)) {
++        errno = EINVAL;
++        return -1;
++    }
++
+     dirfd = local_opendir_nofollow(fs_ctx, dir_path->data);
+     if (dirfd == -1) {
+         return -1;
+@@ -826,6 +855,12 @@ static int local_link(FsContext *ctx, V9fsPath *oldpath,
+     int ret = -1;
+     int odirfd, ndirfd;
+ 
++    if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
++        local_is_mapped_file_metadata(ctx, name)) {
++        errno = EINVAL;
++        return -1;
++    }
++
+     odirfd = local_opendir_nofollow(ctx, odirpath);
+     if (odirfd == -1) {
+         goto out;
+@@ -1096,6 +1131,12 @@ static int local_lremovexattr(FsContext *ctx, V9fsPath 
*fs_path,
+ static int local_name_to_path(FsContext *ctx, V9fsPath *dir_path,
+                               const char *name, V9fsPath *target)
+ {
++    if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
++        local_is_mapped_file_metadata(ctx, name)) {
++        errno = EINVAL;
++        return -1;
++    }
++
+     if (dir_path) {
+         v9fs_path_sprintf(target, "%s/%s", dir_path->data, name);
+     } else if (strcmp(name, "/")) {
+@@ -1116,6 +1157,13 @@ static int local_renameat(FsContext *ctx, V9fsPath 
*olddir,
+     int ret;
+     int odirfd, ndirfd;
+ 
++    if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
++        (local_is_mapped_file_metadata(ctx, old_name) ||
++         local_is_mapped_file_metadata(ctx, new_name))) {
++        errno = EINVAL;
++        return -1;
++    }
++
+     odirfd = local_opendir_nofollow(ctx, olddir->data);
+     if (odirfd == -1) {
+         return -1;
+@@ -1206,6 +1254,12 @@ static int local_unlinkat(FsContext *ctx, V9fsPath *dir,
+     int ret;
+     int dirfd;
+ 
++    if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
++        local_is_mapped_file_metadata(ctx, name)) {
++        errno = EINVAL;
++        return -1;
++    }
++
+     dirfd = local_opendir_nofollow(ctx, dir->data);
+     if (dirfd == -1) {
+         return -1;
+-- 
+2.13.0
+

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
deleted file mode 100644
index 3af1697..0000000
--- a/app-emulation/qemu/files/qemu-2.9.0-CVE-2017-7539.patch
+++ /dev/null
@@ -1,601 +0,0 @@
-From 2b0bbc4f8809c972bad134bc1a2570dbb01dea0b Mon Sep 17 00:00:00 2001
-From: Vladimir Sementsov-Ogievskiy <[email protected]>
-Date: Fri, 2 Jun 2017 18:01:41 +0300
-Subject: [PATCH] nbd/server: get rid of nbd_negotiate_read and friends
-
-Functions nbd_negotiate_{read,write,drop_sync} were introduced in
-1a6245a5b, when nbd_rwv (was nbd_wr_sync) was working through
-qemu_co_sendv_recvv (the path is nbd_wr_sync -> qemu_co_{recv/send} ->
-qemu_co_send_recv -> qemu_co_sendv_recvv), which just yields, without
-setting any handlers. But starting from ff82911cd nbd_rwv (was
-nbd_wr_syncv) works through qio_channel_yield() which sets handlers, so
-watchers are redundant in nbd_negotiate_{read,write,drop_sync}, then,
-let's just use nbd_{read,write,drop} functions.
-
-Functions nbd_{read,write,drop} has errp parameter, which is unused in
-this patch. This will be fixed later.
-
-Signed-off-by: Vladimir Sementsov-Ogievskiy <[email protected]>
-Reviewed-by: Eric Blake <[email protected]>
-Message-Id: <[email protected]>
-Signed-off-by: Paolo Bonzini <[email protected]>
----
- nbd/server.c | 107 ++++++++++++-----------------------------------------------
- 1 file changed, 22 insertions(+), 85 deletions(-)
-
-diff --git a/nbd/client.c b/nbd/client.c
-index a58fb02..6b74a62 100644
---- a/nbd/client.c
-+++ b/nbd/client.c
-@@ -86,9 +86,9 @@ static QTAILQ_HEAD(, NBDExport) exports = 
QTAILQ_HEAD_INITIALIZER(exports);
- 
- */
- 
--/* Discard length bytes from channel.  Return -errno on failure, or
-- * the amount of bytes consumed. */
--static ssize_t drop_sync(QIOChannel *ioc, size_t size)
-+/* Discard length bytes from channel.  Return -errno on failure and 0 on
-+ * success*/
-+static int drop_sync(QIOChannel *ioc, size_t size)
- {
-     ssize_t ret = 0;
-     char small[1024];
-@@ -96,14 +96,13 @@ static ssize_t drop_sync(QIOChannel *ioc, size_t size)
- 
-     buffer = sizeof(small) >= size ? small : g_malloc(MIN(65536, size));
-     while (size > 0) {
--        ssize_t count = read_sync(ioc, buffer, MIN(65536, size));
-+        ssize_t count = MIN(65536, size);
-+        ret = read_sync(ioc, buffer, MIN(65536, size));
- 
--        if (count <= 0) {
-+        if (ret < 0) {
-             goto cleanup;
-         }
--        assert(count <= size);
-         size -= count;
--        ret += count;
-     }
- 
-  cleanup:
-@@ -136,12 +135,12 @@ static int nbd_send_option_request(QIOChannel *ioc, 
uint32_t opt,
-     stl_be_p(&req.option, opt);
-     stl_be_p(&req.length, len);
- 
--    if (write_sync(ioc, &req, sizeof(req)) != sizeof(req)) {
-+    if (write_sync(ioc, &req, sizeof(req)) < 0) {
-         error_setg(errp, "Failed to send option request header");
-         return -1;
-     }
- 
--    if (len && write_sync(ioc, (char *) data, len) != len) {
-+    if (len && write_sync(ioc, (char *) data, len) < 0) {
-         error_setg(errp, "Failed to send option request data");
-         return -1;
-     }
-@@ -170,7 +169,7 @@ static int nbd_receive_option_reply(QIOChannel *ioc, 
uint32_t opt,
-                                     nbd_opt_reply *reply, Error **errp)
- {
-     QEMU_BUILD_BUG_ON(sizeof(*reply) != 20);
--    if (read_sync(ioc, reply, sizeof(*reply)) != sizeof(*reply)) {
-+    if (read_sync(ioc, reply, sizeof(*reply)) < 0) {
-         error_setg(errp, "failed to read option reply");
-         nbd_send_opt_abort(ioc);
-         return -1;
-@@ -219,7 +218,7 @@ static int nbd_handle_reply_err(QIOChannel *ioc, 
nbd_opt_reply *reply,
-             goto cleanup;
-         }
-         msg = g_malloc(reply->length + 1);
--        if (read_sync(ioc, msg, reply->length) != reply->length) {
-+        if (read_sync(ioc, msg, reply->length) < 0) {
-             error_setg(errp, "failed to read option error message");
-             goto cleanup;
-         }
-@@ -321,7 +320,7 @@ static int nbd_receive_list(QIOChannel *ioc, const char 
*want, bool *match,
-         nbd_send_opt_abort(ioc);
-         return -1;
-     }
--    if (read_sync(ioc, &namelen, sizeof(namelen)) != sizeof(namelen)) {
-+    if (read_sync(ioc, &namelen, sizeof(namelen)) < 0) {
-         error_setg(errp, "failed to read option name length");
-         nbd_send_opt_abort(ioc);
-         return -1;
-@@ -334,7 +333,7 @@ static int nbd_receive_list(QIOChannel *ioc, const char 
*want, bool *match,
-         return -1;
-     }
-     if (namelen != strlen(want)) {
--        if (drop_sync(ioc, len) != len) {
-+        if (drop_sync(ioc, len) < 0) {
-             error_setg(errp, "failed to skip export name with wrong length");
-             nbd_send_opt_abort(ioc);
-             return -1;
-@@ -343,14 +342,14 @@ static int nbd_receive_list(QIOChannel *ioc, const char 
*want, bool *match,
-     }
- 
-     assert(namelen < sizeof(name));
--    if (read_sync(ioc, name, namelen) != namelen) {
-+    if (read_sync(ioc, name, namelen) < 0) {
-         error_setg(errp, "failed to read export name");
-         nbd_send_opt_abort(ioc);
-         return -1;
-     }
-     name[namelen] = '\0';
-     len -= namelen;
--    if (drop_sync(ioc, len) != len) {
-+    if (drop_sync(ioc, len) < 0) {
-         error_setg(errp, "failed to read export description");
-         nbd_send_opt_abort(ioc);
-         return -1;
-@@ -477,7 +476,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char 
*name, uint16_t *flags,
-         goto fail;
-     }
- 
--    if (read_sync(ioc, buf, 8) != 8) {
-+    if (read_sync(ioc, buf, 8) < 0) {
-         error_setg(errp, "Failed to read data");
-         goto fail;
-     }
-@@ -503,7 +502,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char 
*name, uint16_t *flags,
-         goto fail;
-     }
- 
--    if (read_sync(ioc, &magic, sizeof(magic)) != sizeof(magic)) {
-+    if (read_sync(ioc, &magic, sizeof(magic)) < 0) {
-         error_setg(errp, "Failed to read magic");
-         goto fail;
-     }
-@@ -515,8 +514,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char 
*name, uint16_t *flags,
-         uint16_t globalflags;
-         bool fixedNewStyle = false;
- 
--        if (read_sync(ioc, &globalflags, sizeof(globalflags)) !=
--            sizeof(globalflags)) {
-+        if (read_sync(ioc, &globalflags, sizeof(globalflags)) < 0) {
-             error_setg(errp, "Failed to read server flags");
-             goto fail;
-         }
-@@ -534,8 +532,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char 
*name, uint16_t *flags,
-         }
-         /* client requested flags */
-         clientflags = cpu_to_be32(clientflags);
--        if (write_sync(ioc, &clientflags, sizeof(clientflags)) !=
--            sizeof(clientflags)) {
-+        if (write_sync(ioc, &clientflags, sizeof(clientflags)) < 0) {
-             error_setg(errp, "Failed to send clientflags field");
-             goto fail;
-         }
-@@ -573,13 +570,13 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char 
*name, uint16_t *flags,
-         }
- 
-         /* Read the response */
--        if (read_sync(ioc, &s, sizeof(s)) != sizeof(s)) {
-+        if (read_sync(ioc, &s, sizeof(s)) < 0) {
-             error_setg(errp, "Failed to read export length");
-             goto fail;
-         }
-         *size = be64_to_cpu(s);
- 
--        if (read_sync(ioc, flags, sizeof(*flags)) != sizeof(*flags)) {
-+        if (read_sync(ioc, flags, sizeof(*flags)) < 0) {
-             error_setg(errp, "Failed to read export flags");
-             goto fail;
-         }
-@@ -596,14 +593,14 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char 
*name, uint16_t *flags,
-             goto fail;
-         }
- 
--        if (read_sync(ioc, &s, sizeof(s)) != sizeof(s)) {
-+        if (read_sync(ioc, &s, sizeof(s)) < 0) {
-             error_setg(errp, "Failed to read export length");
-             goto fail;
-         }
-         *size = be64_to_cpu(s);
-         TRACE("Size is %" PRIu64, *size);
- 
--        if (read_sync(ioc, &oldflags, sizeof(oldflags)) != sizeof(oldflags)) {
-+        if (read_sync(ioc, &oldflags, sizeof(oldflags)) < 0) {
-             error_setg(errp, "Failed to read export flags");
-             goto fail;
-         }
-@@ -619,7 +616,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char 
*name, uint16_t *flags,
-     }
- 
-     TRACE("Size is %" PRIu64 ", export flags %" PRIx16, *size, *flags);
--    if (zeroes && drop_sync(ioc, 124) != 124) {
-+    if (zeroes && drop_sync(ioc, 124) < 0) {
-         error_setg(errp, "Failed to read reserved block");
-         goto fail;
-     }
-@@ -744,7 +741,6 @@ int nbd_disconnect(int fd)
- ssize_t nbd_send_request(QIOChannel *ioc, NBDRequest *request)
- {
-     uint8_t buf[NBD_REQUEST_SIZE];
--    ssize_t ret;
- 
-     TRACE("Sending request to server: "
-           "{ .from = %" PRIu64", .len = %" PRIu32 ", .handle = %" PRIu64
-@@ -759,16 +755,7 @@ ssize_t nbd_send_request(QIOChannel *ioc, NBDRequest 
*request)
-     stq_be_p(buf + 16, request->from);
-     stl_be_p(buf + 24, request->len);
- 
--    ret = write_sync(ioc, buf, sizeof(buf));
--    if (ret < 0) {
--        return ret;
--    }
--
--    if (ret != sizeof(buf)) {
--        LOG("writing to socket failed");
--        return -EINVAL;
--    }
--    return 0;
-+    return write_sync(ioc, buf, sizeof(buf));
- }
- 
- ssize_t nbd_receive_reply(QIOChannel *ioc, NBDReply *reply)
-@@ -777,7 +764,7 @@ ssize_t nbd_receive_reply(QIOChannel *ioc, NBDReply *reply)
-     uint32_t magic;
-     ssize_t ret;
- 
--    ret = read_sync(ioc, buf, sizeof(buf));
-+    ret = read_sync_eof(ioc, buf, sizeof(buf));
-     if (ret <= 0) {
-         return ret;
-     }
-diff --git a/nbd/nbd-internal.h b/nbd/nbd-internal.h
-index f43d990..e6bbc7c 100644
---- a/nbd/nbd-internal.h
-+++ b/nbd/nbd-internal.h
-@@ -94,7 +94,13 @@
- #define NBD_ENOSPC     28
- #define NBD_ESHUTDOWN  108
- 
--static inline ssize_t read_sync(QIOChannel *ioc, void *buffer, size_t size)
-+/* read_sync_eof
-+ * Tries to read @size bytes from @ioc. Returns number of bytes actually read.
-+ * May return a value >= 0 and < size only on EOF, i.e. when iteratively 
called
-+ * qio_channel_readv() returns 0. So, there are no needs to call read_sync_eof
-+ * iteratively.
-+ */
-+static inline ssize_t read_sync_eof(QIOChannel *ioc, void *buffer, size_t 
size)
- {
-     struct iovec iov = { .iov_base = buffer, .iov_len = size };
-     /* Sockets are kept in blocking mode in the negotiation phase.  After
-@@ -105,12 +111,32 @@ static inline ssize_t read_sync(QIOChannel *ioc, void 
*buffer, size_t size)
-     return nbd_wr_syncv(ioc, &iov, 1, size, true);
- }
- 
--static inline ssize_t write_sync(QIOChannel *ioc, const void *buffer,
--                                 size_t size)
-+/* read_sync
-+ * Reads @size bytes from @ioc. Returns 0 on success.
-+ */
-+static inline int read_sync(QIOChannel *ioc, void *buffer, size_t size)
-+{
-+    ssize_t ret = read_sync_eof(ioc, buffer, size);
-+
-+    if (ret >= 0 && ret != size) {
-+        ret = -EINVAL;
-+    }
-+
-+    return ret < 0 ? ret : 0;
-+}
-+
-+/* write_sync
-+ * Writes @size bytes to @ioc. Returns 0 on success.
-+ */
-+static inline int write_sync(QIOChannel *ioc, const void *buffer, size_t size)
- {
-     struct iovec iov = { .iov_base = (void *) buffer, .iov_len = size };
- 
--    return nbd_wr_syncv(ioc, &iov, 1, size, false);
-+    ssize_t ret = nbd_wr_syncv(ioc, &iov, 1, size, false);
-+
-+    assert(ret < 0 || ret == size);
-+
-+    return ret < 0 ? ret : 0;
- }
- 
- struct NBDTLSHandshakeData {
-diff --git a/nbd/server.c b/nbd/server.c
-index 924a1fe..a1f106b 100644
---- a/nbd/server.c
-+++ b/nbd/server.c
-@@ -104,69 +104,6 @@ struct NBDClient {
- 
- static void nbd_client_receive_next_request(NBDClient *client);
- 
--static gboolean nbd_negotiate_continue(QIOChannel *ioc,
--                                       GIOCondition condition,
--                                       void *opaque)
--{
--    qemu_coroutine_enter(opaque);
--    return TRUE;
--}
--
--static ssize_t nbd_negotiate_read(QIOChannel *ioc, void *buffer, size_t size)
--{
--    ssize_t ret;
--    guint watch;
--
--    assert(qemu_in_coroutine());
--    /* Negotiation are always in main loop. */
--    watch = qio_channel_add_watch(ioc,
--                                  G_IO_IN,
--                                  nbd_negotiate_continue,
--                                  qemu_coroutine_self(),
--                                  NULL);
--    ret = read_sync(ioc, buffer, size);
--    g_source_remove(watch);
--    return ret;
--
--}
--
--static ssize_t nbd_negotiate_write(QIOChannel *ioc, const void *buffer,
--                                   size_t size)
--{
--    ssize_t ret;
--    guint watch;
--
--    assert(qemu_in_coroutine());
--    /* Negotiation are always in main loop. */
--    watch = qio_channel_add_watch(ioc,
--                                  G_IO_OUT,
--                                  nbd_negotiate_continue,
--                                  qemu_coroutine_self(),
--                                  NULL);
--    ret = write_sync(ioc, buffer, size);
--    g_source_remove(watch);
--    return ret;
--}
--
--static ssize_t nbd_negotiate_drop_sync(QIOChannel *ioc, size_t size)
--{
--    ssize_t ret, dropped = size;
--    uint8_t *buffer = g_malloc(MIN(65536, size));
--
--    while (size > 0) {
--        ret = nbd_negotiate_read(ioc, buffer, MIN(65536, size));
--        if (ret < 0) {
--            g_free(buffer);
--            return ret;
--        }
--
--        assert(ret <= size);
--        size -= ret;
--    }
--
--    g_free(buffer);
--    return dropped;
--}
- 
- /* Basic flow for negotiation
- 
-@@ -206,22 +143,22 @@ static int nbd_negotiate_send_rep_len(QIOChannel *ioc, 
uint32_t type,
-           type, opt, len);
- 
-     magic = cpu_to_be64(NBD_REP_MAGIC);
--    if (nbd_negotiate_write(ioc, &magic, sizeof(magic)) != sizeof(magic)) {
-+    if (nbd_write(ioc, &magic, sizeof(magic), NULL) < 0) {
-         LOG("write failed (rep magic)");
-         return -EINVAL;
-     }
-     opt = cpu_to_be32(opt);
--    if (nbd_negotiate_write(ioc, &opt, sizeof(opt)) != sizeof(opt)) {
-+    if (nbd_write(ioc, &opt, sizeof(opt), NULL) < 0) {
-         LOG("write failed (rep opt)");
-         return -EINVAL;
-     }
-     type = cpu_to_be32(type);
--    if (nbd_negotiate_write(ioc, &type, sizeof(type)) != sizeof(type)) {
-+    if (nbd_write(ioc, &type, sizeof(type), NULL) < 0) {
-         LOG("write failed (rep type)");
-         return -EINVAL;
-     }
-     len = cpu_to_be32(len);
--    if (nbd_negotiate_write(ioc, &len, sizeof(len)) != sizeof(len)) {
-+    if (nbd_write(ioc, &len, sizeof(len), NULL) < 0) {
-         LOG("write failed (rep data length)");
-         return -EINVAL;
-     }
-@@ -256,7 +193,7 @@ nbd_negotiate_send_rep_err(QIOChannel *ioc, uint32_t type,
-     if (ret < 0) {
-         goto out;
-     }
--    if (nbd_negotiate_write(ioc, msg, len) != len) {
-+    if (nbd_write(ioc, msg, len, NULL) < 0) {
-         LOG("write failed (error message)");
-         ret = -EIO;
-     } else {
-@@ -287,15 +224,15 @@ static int nbd_negotiate_send_rep_list(QIOChannel *ioc, 
NBDExport *exp)
-     }
- 
-     len = cpu_to_be32(name_len);
--    if (nbd_negotiate_write(ioc, &len, sizeof(len)) != sizeof(len)) {
-+    if (nbd_write(ioc, &len, sizeof(len), NULL) < 0) {
-         LOG("write failed (name length)");
-         return -EINVAL;
-     }
--    if (nbd_negotiate_write(ioc, name, name_len) != name_len) {
-+    if (nbd_write(ioc, name, name_len, NULL) < 0) {
-         LOG("write failed (name buffer)");
-         return -EINVAL;
-     }
--    if (nbd_negotiate_write(ioc, desc, desc_len) != desc_len) {
-+    if (nbd_write(ioc, desc, desc_len, NULL) < 0) {
-         LOG("write failed (description buffer)");
-         return -EINVAL;
-     }
-@@ -309,7 +246,7 @@ static int nbd_negotiate_handle_list(NBDClient *client, 
uint32_t length)
-     NBDExport *exp;
- 
-     if (length) {
--        if (nbd_negotiate_drop_sync(client->ioc, length) != length) {
-+        if (nbd_drop(client->ioc, length, NULL) < 0) {
-             return -EIO;
-         }
-         return nbd_negotiate_send_rep_err(client->ioc,
-@@ -340,7 +277,7 @@ static int nbd_negotiate_handle_export_name(NBDClient 
*client, uint32_t length)
-         LOG("Bad length received");
-         goto fail;
-     }
--    if (nbd_negotiate_read(client->ioc, name, length) != length) {
-+    if (nbd_read(client->ioc, name, length, NULL) < 0) {
-         LOG("read failed");
-         goto fail;
-     }
-@@ -373,7 +310,7 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient 
*client,
-     TRACE("Setting up TLS");
-     ioc = client->ioc;
-     if (length) {
--        if (nbd_negotiate_drop_sync(ioc, length) != length) {
-+        if (nbd_drop(ioc, length, NULL) < 0) {
-             return NULL;
-         }
-         nbd_negotiate_send_rep_err(ioc, NBD_REP_ERR_INVALID, NBD_OPT_STARTTLS,
-@@ -437,8 +374,7 @@ static int nbd_negotiate_options(NBDClient *client)
-         ...           Rest of request
-     */
- 
--    if (nbd_negotiate_read(client->ioc, &flags, sizeof(flags)) !=
--        sizeof(flags)) {
-+    if (nbd_read(client->ioc, &flags, sizeof(flags), NULL) < 0) {
-         LOG("read failed");
-         return -EIO;
-     }
-@@ -464,8 +400,7 @@ static int nbd_negotiate_options(NBDClient *client)
-         uint32_t clientflags, length;
-         uint64_t magic;
- 
--        if (nbd_negotiate_read(client->ioc, &magic, sizeof(magic)) !=
--            sizeof(magic)) {
-+        if (nbd_read(client->ioc, &magic, sizeof(magic), NULL) < 0) {
-             LOG("read failed");
-             return -EINVAL;
-         }
-@@ -475,15 +410,15 @@ static int nbd_negotiate_options(NBDClient *client)
-             return -EINVAL;
-         }
- 
--        if (nbd_negotiate_read(client->ioc, &clientflags,
--                               sizeof(clientflags)) != sizeof(clientflags)) {
-+        if (nbd_read(client->ioc, &clientflags,
-+                      sizeof(clientflags), NULL) < 0)
-+        {
-             LOG("read failed");
-             return -EINVAL;
-         }
-         clientflags = be32_to_cpu(clientflags);
- 
--        if (nbd_negotiate_read(client->ioc, &length, sizeof(length)) !=
--            sizeof(length)) {
-+        if (nbd_read(client->ioc, &length, sizeof(length), NULL) < 0) {
-             LOG("read failed");
-             return -EINVAL;
-         }
-@@ -513,7 +448,7 @@ static int nbd_negotiate_options(NBDClient *client)
-                 return -EINVAL;
- 
-             default:
--                if (nbd_negotiate_drop_sync(client->ioc, length) != length) {
-+                if (nbd_drop(client->ioc, length, NULL) < 0) {
-                     return -EIO;
-                 }
-                 ret = nbd_negotiate_send_rep_err(client->ioc,
-@@ -551,7 +486,7 @@ static int nbd_negotiate_options(NBDClient *client)
-                 return nbd_negotiate_handle_export_name(client, length);
- 
-             case NBD_OPT_STARTTLS:
--                if (nbd_negotiate_drop_sync(client->ioc, length) != length) {
-+                if (nbd_drop(client->ioc, length, NULL) < 0) {
-                     return -EIO;
-                 }
-                 if (client->tlscreds) {
-@@ -570,7 +505,7 @@ static int nbd_negotiate_options(NBDClient *client)
-                 }
-                 break;
-             default:
--                if (nbd_negotiate_drop_sync(client->ioc, length) != length) {
-+                if (nbd_drop(client->ioc, length, NULL) < 0) {
-                     return -EIO;
-                 }
-                 ret = nbd_negotiate_send_rep_err(client->ioc,
-@@ -659,12 +594,12 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData 
*data)
-             TRACE("TLS cannot be enabled with oldstyle protocol");
-             goto fail;
-         }
--        if (nbd_negotiate_write(client->ioc, buf, sizeof(buf)) != 
sizeof(buf)) {
-+        if (nbd_write(client->ioc, buf, sizeof(buf), NULL) < 0) {
-             LOG("write failed");
-             goto fail;
-         }
-     } else {
--        if (nbd_negotiate_write(client->ioc, buf, 18) != 18) {
-+        if (nbd_write(client->ioc, buf, 18, NULL) < 0) {
-             LOG("write failed");
-             goto fail;
-         }
-@@ -679,7 +614,7 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData 
*data)
-         stq_be_p(buf + 18, client->exp->size);
-         stw_be_p(buf + 26, client->exp->nbdflags | myflags);
-         len = client->no_zeroes ? 10 : sizeof(buf) - 18;
--        if (nbd_negotiate_write(client->ioc, buf + 18, len) != len) {
-+        if (nbd_write(client->ioc, buf + 18, len, NULL) < 0) {
-             LOG("write failed");
-             goto fail;
-         }
-@@ -702,11 +637,6 @@ static ssize_t nbd_receive_request(QIOChannel *ioc, 
NBDRequest *request)
-         return ret;
-     }
- 
--    if (ret != sizeof(buf)) {
--        LOG("read failed");
--        return -EINVAL;
--    }
--
-     /* Request
-        [ 0 ..  3]   magic   (NBD_REQUEST_MAGIC)
-        [ 4 ..  5]   flags   (NBD_CMD_FLAG_FUA, ...)
-@@ -737,7 +667,6 @@ static ssize_t nbd_receive_request(QIOChannel *ioc, 
NBDRequest *request)
- static ssize_t nbd_send_reply(QIOChannel *ioc, NBDReply *reply)
- {
-     uint8_t buf[NBD_REPLY_SIZE];
--    ssize_t ret;
- 
-     reply->error = system_errno_to_nbd_errno(reply->error);
- 
-@@ -754,16 +683,7 @@ static ssize_t nbd_send_reply(QIOChannel *ioc, NBDReply 
*reply)
-     stl_be_p(buf + 4, reply->error);
-     stq_be_p(buf + 8, reply->handle);
- 
--    ret = write_sync(ioc, buf, sizeof(buf));
--    if (ret < 0) {
--        return ret;
--    }
--
--    if (ret != sizeof(buf)) {
--        LOG("writing to socket failed");
--        return -EINVAL;
--    }
--    return 0;
-+    return write_sync(ioc, buf, sizeof(buf));
- }
- 
- #define MAX_NBD_REQUESTS 16
-@@ -1067,7 +987,7 @@ static ssize_t nbd_co_send_reply(NBDRequestData *req, 
NBDReply *reply,
-         rc = nbd_send_reply(client->ioc, reply);
-         if (rc >= 0) {
-             ret = write_sync(client->ioc, req->data, len);
--            if (ret != len) {
-+            if (ret < 0) {
-                 rc = -EIO;
-             }
-         }
-@@ -1141,7 +1061,7 @@ static ssize_t nbd_co_receive_request(NBDRequestData 
*req,
-     if (request->type == NBD_CMD_WRITE) {
-         TRACE("Reading %" PRIu32 " byte(s)", request->len);
- 
--        if (read_sync(client->ioc, req->data, request->len) != request->len) {
-+        if (read_sync(client->ioc, req->data, request->len) < 0) {
-             LOG("reading from socket failed");
-             rc = -EIO;
-             goto out;

Reply via email to