|
|
76daa3 |
From b202cbe30ea881c40defe4e7dde664e0b99e8c06 Mon Sep 17 00:00:00 2001
|
|
|
76daa3 |
From: Eric Blake <eblake@redhat.com>
|
|
|
76daa3 |
Date: Wed, 19 Jul 2017 18:02:02 +0200
|
|
|
76daa3 |
Subject: [PATCH 05/17] nbd/server: get rid of nbd_negotiate_read and friends
|
|
|
76daa3 |
|
|
|
76daa3 |
RH-Author: Eric Blake <eblake@redhat.com>
|
|
|
76daa3 |
Message-id: <20170719180202.23329-5-eblake@redhat.com>
|
|
|
76daa3 |
Patchwork-id: 75816
|
|
|
76daa3 |
O-Subject: [RHEV-7.4.z qemu-kvm-rhev PATCH 4/4] nbd/server: get rid of nbd_negotiate_read and friends
|
|
|
76daa3 |
Bugzilla: 1473638
|
|
|
76daa3 |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
76daa3 |
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
76daa3 |
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
|
|
|
76daa3 |
|
|
|
76daa3 |
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
|
|
76daa3 |
|
|
|
76daa3 |
Functions nbd_negotiate_{read,write,drop_sync} were introduced in
|
|
|
76daa3 |
1a6245a5b, when nbd_rwv (was nbd_wr_sync) was working through
|
|
|
76daa3 |
qemu_co_sendv_recvv (the path is nbd_wr_sync -> qemu_co_{recv/send} ->
|
|
|
76daa3 |
qemu_co_send_recv -> qemu_co_sendv_recvv), which just yields, without
|
|
|
76daa3 |
setting any handlers. But starting from ff82911cd nbd_rwv (was
|
|
|
76daa3 |
nbd_wr_syncv) works through qio_channel_yield() which sets handlers, so
|
|
|
76daa3 |
watchers are redundant in nbd_negotiate_{read,write,drop_sync}, then,
|
|
|
76daa3 |
let's just use nbd_{read,write,drop} functions.
|
|
|
76daa3 |
|
|
|
76daa3 |
Functions nbd_{read,write,drop} has errp parameter, which is unused in
|
|
|
76daa3 |
this patch. This will be fixed later.
|
|
|
76daa3 |
|
|
|
76daa3 |
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
|
|
76daa3 |
Reviewed-by: Eric Blake <eblake@redhat.com>
|
|
|
76daa3 |
Message-Id: <20170602150150.258222-4-vsementsov@virtuozzo.com>
|
|
|
76daa3 |
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
76daa3 |
(cherry picked from commit 2b0bbc4f8809c972bad134bc1a2570dbb01dea0b)
|
|
|
76daa3 |
|
|
|
76daa3 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
76daa3 |
|
|
|
76daa3 |
Conflicts:
|
|
|
76daa3 |
nbd/server.c - missing errp addition (e44ed99) and bulk
|
|
|
76daa3 |
rename (d1fdf25)
|
|
|
76daa3 |
Fixes CVE-2017-7539
|
|
|
76daa3 |
|
|
|
76daa3 |
Signed-off-by: Eric Blake <eblake@redhat.com>
|
|
|
76daa3 |
---
|
|
|
76daa3 |
nbd/server.c | 106 ++++++++++++-----------------------------------------------
|
|
|
76daa3 |
1 file changed, 21 insertions(+), 85 deletions(-)
|
|
|
76daa3 |
|
|
|
76daa3 |
diff --git a/nbd/server.c b/nbd/server.c
|
|
|
76daa3 |
index b44cbe6..8e3b8e5 100644
|
|
|
76daa3 |
--- a/nbd/server.c
|
|
|
76daa3 |
+++ b/nbd/server.c
|
|
|
76daa3 |
@@ -104,69 +104,6 @@ struct NBDClient {
|
|
|
76daa3 |
|
|
|
76daa3 |
static void nbd_client_receive_next_request(NBDClient *client);
|
|
|
76daa3 |
|
|
|
76daa3 |
-static gboolean nbd_negotiate_continue(QIOChannel *ioc,
|
|
|
76daa3 |
- GIOCondition condition,
|
|
|
76daa3 |
- void *opaque)
|
|
|
76daa3 |
-{
|
|
|
76daa3 |
- qemu_coroutine_enter(opaque);
|
|
|
76daa3 |
- return TRUE;
|
|
|
76daa3 |
-}
|
|
|
76daa3 |
-
|
|
|
76daa3 |
-static int nbd_negotiate_read(QIOChannel *ioc, void *buffer, size_t size)
|
|
|
76daa3 |
-{
|
|
|
76daa3 |
- ssize_t ret;
|
|
|
76daa3 |
- guint watch;
|
|
|
76daa3 |
-
|
|
|
76daa3 |
- assert(qemu_in_coroutine());
|
|
|
76daa3 |
- /* Negotiation are always in main loop. */
|
|
|
76daa3 |
- watch = qio_channel_add_watch(ioc,
|
|
|
76daa3 |
- G_IO_IN,
|
|
|
76daa3 |
- nbd_negotiate_continue,
|
|
|
76daa3 |
- qemu_coroutine_self(),
|
|
|
76daa3 |
- NULL);
|
|
|
76daa3 |
- ret = read_sync(ioc, buffer, size);
|
|
|
76daa3 |
- g_source_remove(watch);
|
|
|
76daa3 |
- return ret;
|
|
|
76daa3 |
-
|
|
|
76daa3 |
-}
|
|
|
76daa3 |
-
|
|
|
76daa3 |
-static int nbd_negotiate_write(QIOChannel *ioc, const void *buffer, size_t size)
|
|
|
76daa3 |
-{
|
|
|
76daa3 |
- ssize_t ret;
|
|
|
76daa3 |
- guint watch;
|
|
|
76daa3 |
-
|
|
|
76daa3 |
- assert(qemu_in_coroutine());
|
|
|
76daa3 |
- /* Negotiation are always in main loop. */
|
|
|
76daa3 |
- watch = qio_channel_add_watch(ioc,
|
|
|
76daa3 |
- G_IO_OUT,
|
|
|
76daa3 |
- nbd_negotiate_continue,
|
|
|
76daa3 |
- qemu_coroutine_self(),
|
|
|
76daa3 |
- NULL);
|
|
|
76daa3 |
- ret = write_sync(ioc, buffer, size);
|
|
|
76daa3 |
- g_source_remove(watch);
|
|
|
76daa3 |
- return ret;
|
|
|
76daa3 |
-}
|
|
|
76daa3 |
-
|
|
|
76daa3 |
-static int nbd_negotiate_drop_sync(QIOChannel *ioc, size_t size)
|
|
|
76daa3 |
-{
|
|
|
76daa3 |
- ssize_t ret;
|
|
|
76daa3 |
- uint8_t *buffer = g_malloc(MIN(65536, size));
|
|
|
76daa3 |
-
|
|
|
76daa3 |
- while (size > 0) {
|
|
|
76daa3 |
- size_t count = MIN(65536, size);
|
|
|
76daa3 |
- ret = nbd_negotiate_read(ioc, buffer, count);
|
|
|
76daa3 |
- if (ret < 0) {
|
|
|
76daa3 |
- g_free(buffer);
|
|
|
76daa3 |
- return ret;
|
|
|
76daa3 |
- }
|
|
|
76daa3 |
-
|
|
|
76daa3 |
- size -= count;
|
|
|
76daa3 |
- }
|
|
|
76daa3 |
-
|
|
|
76daa3 |
- g_free(buffer);
|
|
|
76daa3 |
- return 0;
|
|
|
76daa3 |
-}
|
|
|
76daa3 |
-
|
|
|
76daa3 |
/* Basic flow for negotiation
|
|
|
76daa3 |
|
|
|
76daa3 |
Server Client
|
|
|
76daa3 |
@@ -205,22 +142,22 @@ static int nbd_negotiate_send_rep_len(QIOChannel *ioc, uint32_t type,
|
|
|
76daa3 |
type, opt, len);
|
|
|
76daa3 |
|
|
|
76daa3 |
magic = cpu_to_be64(NBD_REP_MAGIC);
|
|
|
76daa3 |
- if (nbd_negotiate_write(ioc, &magic, sizeof(magic)) < 0) {
|
|
|
76daa3 |
+ if (write_sync(ioc, &magic, sizeof(magic)) < 0) {
|
|
|
76daa3 |
LOG("write failed (rep magic)");
|
|
|
76daa3 |
return -EINVAL;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
opt = cpu_to_be32(opt);
|
|
|
76daa3 |
- if (nbd_negotiate_write(ioc, &opt, sizeof(opt)) < 0) {
|
|
|
76daa3 |
+ if (write_sync(ioc, &opt, sizeof(opt)) < 0) {
|
|
|
76daa3 |
LOG("write failed (rep opt)");
|
|
|
76daa3 |
return -EINVAL;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
type = cpu_to_be32(type);
|
|
|
76daa3 |
- if (nbd_negotiate_write(ioc, &type, sizeof(type)) < 0) {
|
|
|
76daa3 |
+ if (write_sync(ioc, &type, sizeof(type)) < 0) {
|
|
|
76daa3 |
LOG("write failed (rep type)");
|
|
|
76daa3 |
return -EINVAL;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
len = cpu_to_be32(len);
|
|
|
76daa3 |
- if (nbd_negotiate_write(ioc, &len, sizeof(len)) < 0) {
|
|
|
76daa3 |
+ if (write_sync(ioc, &len, sizeof(len)) < 0) {
|
|
|
76daa3 |
LOG("write failed (rep data length)");
|
|
|
76daa3 |
return -EINVAL;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
@@ -255,7 +192,7 @@ nbd_negotiate_send_rep_err(QIOChannel *ioc, uint32_t type,
|
|
|
76daa3 |
if (ret < 0) {
|
|
|
76daa3 |
goto out;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
- if (nbd_negotiate_write(ioc, msg, len) < 0) {
|
|
|
76daa3 |
+ if (write_sync(ioc, msg, len) < 0) {
|
|
|
76daa3 |
LOG("write failed (error message)");
|
|
|
76daa3 |
ret = -EIO;
|
|
|
76daa3 |
} else {
|
|
|
76daa3 |
@@ -286,15 +223,15 @@ static int nbd_negotiate_send_rep_list(QIOChannel *ioc, NBDExport *exp)
|
|
|
76daa3 |
}
|
|
|
76daa3 |
|
|
|
76daa3 |
len = cpu_to_be32(name_len);
|
|
|
76daa3 |
- if (nbd_negotiate_write(ioc, &len, sizeof(len)) < 0) {
|
|
|
76daa3 |
+ if (write_sync(ioc, &len, sizeof(len)) < 0) {
|
|
|
76daa3 |
LOG("write failed (name length)");
|
|
|
76daa3 |
return -EINVAL;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
- if (nbd_negotiate_write(ioc, name, name_len) < 0) {
|
|
|
76daa3 |
+ if (write_sync(ioc, name, name_len) < 0) {
|
|
|
76daa3 |
LOG("write failed (name buffer)");
|
|
|
76daa3 |
return -EINVAL;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
- if (nbd_negotiate_write(ioc, desc, desc_len) < 0) {
|
|
|
76daa3 |
+ if (write_sync(ioc, desc, desc_len) < 0) {
|
|
|
76daa3 |
LOG("write failed (description buffer)");
|
|
|
76daa3 |
return -EINVAL;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
@@ -308,7 +245,7 @@ static int nbd_negotiate_handle_list(NBDClient *client, uint32_t length)
|
|
|
76daa3 |
NBDExport *exp;
|
|
|
76daa3 |
|
|
|
76daa3 |
if (length) {
|
|
|
76daa3 |
- if (nbd_negotiate_drop_sync(client->ioc, length) < 0) {
|
|
|
76daa3 |
+ if (nbd_drop(client->ioc, length) < 0) {
|
|
|
76daa3 |
return -EIO;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
return nbd_negotiate_send_rep_err(client->ioc,
|
|
|
76daa3 |
@@ -339,7 +276,7 @@ static int nbd_negotiate_handle_export_name(NBDClient *client, uint32_t length)
|
|
|
76daa3 |
LOG("Bad length received");
|
|
|
76daa3 |
goto fail;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
- if (nbd_negotiate_read(client->ioc, name, length) < 0) {
|
|
|
76daa3 |
+ if (read_sync(client->ioc, name, length) < 0) {
|
|
|
76daa3 |
LOG("read failed");
|
|
|
76daa3 |
goto fail;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
@@ -372,7 +309,7 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client,
|
|
|
76daa3 |
TRACE("Setting up TLS");
|
|
|
76daa3 |
ioc = client->ioc;
|
|
|
76daa3 |
if (length) {
|
|
|
76daa3 |
- if (nbd_negotiate_drop_sync(ioc, length) < 0) {
|
|
|
76daa3 |
+ if (nbd_drop(ioc, length) < 0) {
|
|
|
76daa3 |
return NULL;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
nbd_negotiate_send_rep_err(ioc, NBD_REP_ERR_INVALID, NBD_OPT_STARTTLS,
|
|
|
76daa3 |
@@ -436,7 +373,7 @@ static int nbd_negotiate_options(NBDClient *client)
|
|
|
76daa3 |
... Rest of request
|
|
|
76daa3 |
*/
|
|
|
76daa3 |
|
|
|
76daa3 |
- if (nbd_negotiate_read(client->ioc, &flags, sizeof(flags)) < 0) {
|
|
|
76daa3 |
+ if (read_sync(client->ioc, &flags, sizeof(flags)) < 0) {
|
|
|
76daa3 |
LOG("read failed");
|
|
|
76daa3 |
return -EIO;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
@@ -462,7 +399,7 @@ static int nbd_negotiate_options(NBDClient *client)
|
|
|
76daa3 |
uint32_t clientflags, length;
|
|
|
76daa3 |
uint64_t magic;
|
|
|
76daa3 |
|
|
|
76daa3 |
- if (nbd_negotiate_read(client->ioc, &magic, sizeof(magic)) < 0) {
|
|
|
76daa3 |
+ if (read_sync(client->ioc, &magic, sizeof(magic)) < 0) {
|
|
|
76daa3 |
LOG("read failed");
|
|
|
76daa3 |
return -EINVAL;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
@@ -472,15 +409,14 @@ static int nbd_negotiate_options(NBDClient *client)
|
|
|
76daa3 |
return -EINVAL;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
|
|
|
76daa3 |
- if (nbd_negotiate_read(client->ioc, &clientflags,
|
|
|
76daa3 |
- sizeof(clientflags)) < 0)
|
|
|
76daa3 |
+ if (read_sync(client->ioc, &clientflags, sizeof(clientflags)) < 0)
|
|
|
76daa3 |
{
|
|
|
76daa3 |
LOG("read failed");
|
|
|
76daa3 |
return -EINVAL;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
clientflags = be32_to_cpu(clientflags);
|
|
|
76daa3 |
|
|
|
76daa3 |
- if (nbd_negotiate_read(client->ioc, &length, sizeof(length)) < 0) {
|
|
|
76daa3 |
+ if (read_sync(client->ioc, &length, sizeof(length)) < 0) {
|
|
|
76daa3 |
LOG("read failed");
|
|
|
76daa3 |
return -EINVAL;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
@@ -510,7 +446,7 @@ static int nbd_negotiate_options(NBDClient *client)
|
|
|
76daa3 |
return -EINVAL;
|
|
|
76daa3 |
|
|
|
76daa3 |
default:
|
|
|
76daa3 |
- if (nbd_negotiate_drop_sync(client->ioc, length) < 0) {
|
|
|
76daa3 |
+ if (nbd_drop(client->ioc, length) < 0) {
|
|
|
76daa3 |
return -EIO;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
ret = nbd_negotiate_send_rep_err(client->ioc,
|
|
|
76daa3 |
@@ -548,7 +484,7 @@ static int nbd_negotiate_options(NBDClient *client)
|
|
|
76daa3 |
return nbd_negotiate_handle_export_name(client, length);
|
|
|
76daa3 |
|
|
|
76daa3 |
case NBD_OPT_STARTTLS:
|
|
|
76daa3 |
- if (nbd_negotiate_drop_sync(client->ioc, length) < 0) {
|
|
|
76daa3 |
+ if (nbd_drop(client->ioc, length) < 0) {
|
|
|
76daa3 |
return -EIO;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
if (client->tlscreds) {
|
|
|
76daa3 |
@@ -567,7 +503,7 @@ static int nbd_negotiate_options(NBDClient *client)
|
|
|
76daa3 |
}
|
|
|
76daa3 |
break;
|
|
|
76daa3 |
default:
|
|
|
76daa3 |
- if (nbd_negotiate_drop_sync(client->ioc, length) < 0) {
|
|
|
76daa3 |
+ if (nbd_drop(client->ioc, length) < 0) {
|
|
|
76daa3 |
return -EIO;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
ret = nbd_negotiate_send_rep_err(client->ioc,
|
|
|
76daa3 |
@@ -656,12 +592,12 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data)
|
|
|
76daa3 |
TRACE("TLS cannot be enabled with oldstyle protocol");
|
|
|
76daa3 |
goto fail;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
- if (nbd_negotiate_write(client->ioc, buf, sizeof(buf)) < 0) {
|
|
|
76daa3 |
+ if (write_sync(client->ioc, buf, sizeof(buf)) < 0) {
|
|
|
76daa3 |
LOG("write failed");
|
|
|
76daa3 |
goto fail;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
} else {
|
|
|
76daa3 |
- if (nbd_negotiate_write(client->ioc, buf, 18) < 0) {
|
|
|
76daa3 |
+ if (write_sync(client->ioc, buf, 18) < 0) {
|
|
|
76daa3 |
LOG("write failed");
|
|
|
76daa3 |
goto fail;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
@@ -676,7 +612,7 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data)
|
|
|
76daa3 |
stq_be_p(buf + 18, client->exp->size);
|
|
|
76daa3 |
stw_be_p(buf + 26, client->exp->nbdflags | myflags);
|
|
|
76daa3 |
len = client->no_zeroes ? 10 : sizeof(buf) - 18;
|
|
|
76daa3 |
- if (nbd_negotiate_write(client->ioc, buf + 18, len) < 0) {
|
|
|
76daa3 |
+ if (write_sync(client->ioc, buf + 18, len) < 0) {
|
|
|
76daa3 |
LOG("write failed");
|
|
|
76daa3 |
goto fail;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
--
|
|
|
76daa3 |
1.8.3.1
|
|
|
76daa3 |
|