[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-stable] [PATCH 52/56] nbd: Limit nbdflags to 16 bits
From: |
Michael Roth |
Subject: |
[Qemu-stable] [PATCH 52/56] nbd: Limit nbdflags to 16 bits |
Date: |
Mon, 8 Aug 2016 16:04:23 -0500 |
From: Eric Blake <address@hidden>
Rather than asserting that nbdflags is within range, just give
it the correct type to begin with :) nbdflags corresponds to
the per-export portion of NBD Protocol "transmission flags", which
is 16 bits in response to NBD_OPT_EXPORT_NAME and NBD_OPT_GO.
Furthermore, upstream NBD has never passed the global flags to
the kernel via ioctl(NBD_SET_FLAGS) (the ioctl was first
introduced in NBD 2.9.22; then a latent bug in NBD 3.1 actually
tried to OR the global flags with the transmission flags, with
the disaster that the addition of NBD_FLAG_NO_ZEROES in 3.9
caused all earlier NBD 3.x clients to treat every export as
read-only; NBD 3.10 and later intentionally clip things to 16
bits to pass only transmission flags). Qemu should follow suit,
since the current two global flags (NBD_FLAG_FIXED_NEWSTYLE
and NBD_FLAG_NO_ZEROES) have no impact on the kernel's behavior
during transmission.
CC: address@hidden
Signed-off-by: Eric Blake <address@hidden>
Message-Id: <address@hidden>
Signed-off-by: Paolo Bonzini <address@hidden>
(cherry picked from commit 7423f417827146f956df820f172d0bf80a489495)
Signed-off-by: Michael Roth <address@hidden>
---
block/nbd-client.h | 2 +-
include/block/nbd.h | 6 +++---
nbd/client.c | 28 +++++++++++++++-------------
nbd/server.c | 10 ++++------
qemu-nbd.c | 4 ++--
5 files changed, 25 insertions(+), 25 deletions(-)
diff --git a/block/nbd-client.h b/block/nbd-client.h
index bc7aec0..1243612 100644
--- a/block/nbd-client.h
+++ b/block/nbd-client.h
@@ -20,7 +20,7 @@
typedef struct NbdClientSession {
QIOChannelSocket *sioc; /* The master data channel */
QIOChannel *ioc; /* The current I/O channel which may differ (eg TLS) */
- uint32_t nbdflags;
+ uint16_t nbdflags;
off_t size;
CoMutex send_mutex;
diff --git a/include/block/nbd.h b/include/block/nbd.h
index 36dde24..fde4421 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -84,11 +84,11 @@ ssize_t nbd_wr_syncv(QIOChannel *ioc,
size_t offset,
size_t length,
bool do_read);
-int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint32_t *flags,
+int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags,
QCryptoTLSCreds *tlscreds, const char *hostname,
QIOChannel **outioc,
off_t *size, Error **errp);
-int nbd_init(int fd, QIOChannelSocket *sioc, uint32_t flags, off_t size);
+int nbd_init(int fd, QIOChannelSocket *sioc, uint16_t flags, off_t size);
ssize_t nbd_send_request(QIOChannel *ioc, struct nbd_request *request);
ssize_t nbd_receive_reply(QIOChannel *ioc, struct nbd_reply *reply);
int nbd_client(int fd);
@@ -98,7 +98,7 @@ typedef struct NBDExport NBDExport;
typedef struct NBDClient NBDClient;
NBDExport *nbd_export_new(BlockBackend *blk, off_t dev_offset, off_t size,
- uint32_t nbdflags, void (*close)(NBDExport *),
+ uint16_t nbdflags, void (*close)(NBDExport *),
Error **errp);
void nbd_export_close(NBDExport *exp);
void nbd_export_get(NBDExport *exp);
diff --git a/nbd/client.c b/nbd/client.c
index e72befd..1a01b6c 100644
--- a/nbd/client.c
+++ b/nbd/client.c
@@ -406,7 +406,7 @@ static QIOChannel *nbd_receive_starttls(QIOChannel *ioc,
}
-int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint32_t *flags,
+int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags,
QCryptoTLSCreds *tlscreds, const char *hostname,
QIOChannel **outioc,
off_t *size, Error **errp)
@@ -466,7 +466,6 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char
*name, uint32_t *flags,
uint32_t opt;
uint32_t namesize;
uint16_t globalflags;
- uint16_t exportflags;
bool fixedNewStyle = false;
if (read_sync(ioc, &globalflags, sizeof(globalflags)) !=
@@ -475,7 +474,6 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char
*name, uint32_t *flags,
goto fail;
}
globalflags = be16_to_cpu(globalflags);
- *flags = globalflags << 16;
TRACE("Global flags are %" PRIx32, globalflags);
if (globalflags & NBD_FLAG_FIXED_NEWSTYLE) {
fixedNewStyle = true;
@@ -543,17 +541,15 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char
*name, uint32_t *flags,
goto fail;
}
*size = be64_to_cpu(s);
- TRACE("Size is %" PRIu64, *size);
- if (read_sync(ioc, &exportflags, sizeof(exportflags)) !=
- sizeof(exportflags)) {
+ if (read_sync(ioc, flags, sizeof(*flags)) != sizeof(*flags)) {
error_setg(errp, "Failed to read export flags");
goto fail;
}
- exportflags = be16_to_cpu(exportflags);
- *flags |= exportflags;
- TRACE("Export flags are %" PRIx16, exportflags);
+ be16_to_cpus(flags);
} else if (magic == NBD_CLIENT_MAGIC) {
+ uint32_t oldflags;
+
if (name) {
error_setg(errp, "Server does not support export names");
goto fail;
@@ -570,16 +566,22 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char
*name, uint32_t *flags,
*size = be64_to_cpu(s);
TRACE("Size is %" PRIu64, *size);
- if (read_sync(ioc, flags, sizeof(*flags)) != sizeof(*flags)) {
+ if (read_sync(ioc, &oldflags, sizeof(oldflags)) != sizeof(oldflags)) {
error_setg(errp, "Failed to read export flags");
goto fail;
}
- *flags = be32_to_cpu(*flags);
+ be32_to_cpus(&oldflags);
+ if (oldflags & ~0xffff) {
+ error_setg(errp, "Unexpected export flags %0x" PRIx32, oldflags);
+ goto fail;
+ }
+ *flags = oldflags;
} else {
error_setg(errp, "Bad magic received");
goto fail;
}
+ TRACE("Size is %" PRIu64 ", export flags %" PRIx16, *size, *flags);
if (read_sync(ioc, &buf, 124) != 124) {
error_setg(errp, "Failed to read reserved block");
goto fail;
@@ -591,7 +593,7 @@ fail:
}
#ifdef __linux__
-int nbd_init(int fd, QIOChannelSocket *sioc, uint32_t flags, off_t size)
+int nbd_init(int fd, QIOChannelSocket *sioc, uint16_t flags, off_t size)
{
TRACE("Setting NBD socket");
@@ -668,7 +670,7 @@ int nbd_client(int fd)
return ret;
}
#else
-int nbd_init(int fd, QIOChannelSocket *ioc, uint32_t flags, off_t size)
+int nbd_init(int fd, QIOChannelSocket *ioc, uint16_t flags, off_t size)
{
return -ENOTSUP;
}
diff --git a/nbd/server.c b/nbd/server.c
index 2fc6d74..6f83beb 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -62,7 +62,7 @@ struct NBDExport {
char *name;
off_t dev_offset;
off_t size;
- uint32_t nbdflags;
+ uint16_t nbdflags;
QTAILQ_HEAD(, NBDClient) clients;
QTAILQ_ENTRY(NBDExport) next;
@@ -529,8 +529,8 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData
*data)
NBDClient *client = data->client;
char buf[8 + 8 + 8 + 128];
int rc;
- const int myflags = (NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_TRIM |
- NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA);
+ const uint16_t myflags = (NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_TRIM |
+ NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA);
bool oldStyle;
/* Old style negotiation header without options
@@ -560,7 +560,6 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData
*data)
oldStyle = client->exp != NULL && !client->tlscreds;
if (oldStyle) {
- assert ((client->exp->nbdflags & ~65535) == 0);
TRACE("advertising size %" PRIu64 " and flags %x",
client->exp->size, client->exp->nbdflags | myflags);
stq_be_p(buf + 8, NBD_CLIENT_MAGIC);
@@ -591,7 +590,6 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData
*data)
goto fail;
}
- assert ((client->exp->nbdflags & ~65535) == 0);
TRACE("advertising size %" PRIu64 " and flags %x",
client->exp->size, client->exp->nbdflags | myflags);
stq_be_p(buf + 18, client->exp->size);
@@ -813,7 +811,7 @@ static void nbd_eject_notifier(Notifier *n, void *data)
}
NBDExport *nbd_export_new(BlockBackend *blk, off_t dev_offset, off_t size,
- uint32_t nbdflags, void (*close)(NBDExport *),
+ uint16_t nbdflags, void (*close)(NBDExport *),
Error **errp)
{
NBDExport *exp = g_malloc0(sizeof(NBDExport));
diff --git a/qemu-nbd.c b/qemu-nbd.c
index 114d82f..6dea6d6 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -241,7 +241,7 @@ static void *nbd_client_thread(void *arg)
{
char *device = arg;
off_t size;
- uint32_t nbdflags;
+ uint16_t nbdflags;
QIOChannelSocket *sioc;
int fd;
int ret;
@@ -455,7 +455,7 @@ int main(int argc, char **argv)
BlockBackend *blk;
BlockDriverState *bs;
off_t dev_offset = 0;
- uint32_t nbdflags = 0;
+ uint16_t nbdflags = 0;
bool disconnect = false;
const char *bindto = "0.0.0.0";
const char *port = NULL;
--
1.9.1
- [Qemu-stable] [PATCH 46/56] qemu-iotests: Test naming of throttling groups, (continued)
- [Qemu-stable] [PATCH 46/56] qemu-iotests: Test naming of throttling groups, Michael Roth, 2016/08/08
- [Qemu-stable] [PATCH 03/56] vl: change runstate only if new state is different from current state, Michael Roth, 2016/08/08
- [Qemu-stable] [PATCH 45/56] blockdev: Fix regression with the default naming of throttling groups, Michael Roth, 2016/08/08
- [Qemu-stable] [PATCH 42/56] virtio: set low features early on load, Michael Roth, 2016/08/08
- [Qemu-stable] [PATCH 43/56] Revert "virtio-net: unbreak self announcement and guest offloads after migration", Michael Roth, 2016/08/08
- [Qemu-stable] [PATCH 47/56] util: Fix MIN_NON_ZERO, Michael Roth, 2016/08/08
- [Qemu-stable] [PATCH 48/56] block/iscsi: fix rounding in iscsi_allocationmap_set, Michael Roth, 2016/08/08
- [Qemu-stable] [PATCH 50/56] nbd: More debug typo fixes, use correct formats, Michael Roth, 2016/08/08
- [Qemu-stable] [PATCH 04/56] tools: kvm_stat: Powerpc related fixes, Michael Roth, 2016/08/08
- [Qemu-stable] [PATCH 49/56] Fix some typos found by codespell, Michael Roth, 2016/08/08
- [Qemu-stable] [PATCH 52/56] nbd: Limit nbdflags to 16 bits,
Michael Roth <=
- [Qemu-stable] [PATCH 53/56] pcie: fix link active status bit migration, Michael Roth, 2016/08/08
- [Qemu-stable] [PATCH 51/56] nbd: Don't use *_to_cpup() functions, Michael Roth, 2016/08/08
- [Qemu-stable] [PATCH 55/56] virtio: error out if guest exceeds virtqueue size, Michael Roth, 2016/08/08
- [Qemu-stable] [PATCH 54/56] target-i386: fix typo in xsetbv implementation, Michael Roth, 2016/08/08
- [Qemu-stable] [PATCH 06/56] usb:xhci: no DMA on HC reset, Michael Roth, 2016/08/08
- [Qemu-stable] [PATCH 56/56] ide: fix halted IO segfault at reset, Michael Roth, 2016/08/08
- [Qemu-stable] [PATCH 08/56] target-i386: key sfence availability on CPUID_SSE, not CPUID_SSE2, Michael Roth, 2016/08/08
- [Qemu-stable] [PATCH 07/56] target-mips: fix call to memset in soft reset code, Michael Roth, 2016/08/08
- [Qemu-stable] [PATCH 05/56] exec.c: Ensure right alignment also for file backed ram, Michael Roth, 2016/08/08