diff options
author | Eric Blake <eblake@redhat.com> | 2019-11-13 20:46:34 -0600 |
---|---|---|
committer | Eric Blake <eblake@redhat.com> | 2019-11-18 16:01:34 -0600 |
commit | 93676c88d7a5cd5971de94f9091eff8e9773b1af (patch) | |
tree | c6711a35024de53f6af0bacebc3063d40b41d291 /block/nbd.c | |
parent | cf7c49cf6aedb0486ca7ba7c32aa819fe51dadfb (diff) | |
download | qemu-93676c88d7a5cd5971de94f9091eff8e9773b1af.zip qemu-93676c88d7a5cd5971de94f9091eff8e9773b1af.tar.gz qemu-93676c88d7a5cd5971de94f9091eff8e9773b1af.tar.bz2 |
nbd: Don't send oversize strings
Qemu as server currently won't accept export names larger than 256
bytes, nor create dirty bitmap names longer than 1023 bytes, so most
uses of qemu as client or server have no reason to get anywhere near
the NBD spec maximum of a 4k limit per string.
However, we weren't actually enforcing things, ignoring when the
remote side violates the protocol on input, and also having several
code paths where we send oversize strings on output (for example,
qemu-nbd --description could easily send more than 4k). Tighten
things up as follows:
client:
- Perform bounds check on export name and dirty bitmap request prior
to handing it to server
- Validate that copied server replies are not too long (ignoring
NBD_INFO_* replies that are not copied is not too bad)
server:
- Perform bounds check on export name and description prior to
advertising it to client
- Reject client name or metadata query that is too long
- Adjust things to allow full 4k name limit rather than previous
256 byte limit
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20191114024635.11363-4-eblake@redhat.com>
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Diffstat (limited to 'block/nbd.c')
-rw-r--r-- | block/nbd.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/block/nbd.c b/block/nbd.c index 1239761..5f18f78 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -1832,6 +1832,10 @@ static int nbd_process_options(BlockDriverState *bs, QDict *options, } s->export = g_strdup(qemu_opt_get(opts, "export")); + if (s->export && strlen(s->export) > NBD_MAX_STRING_SIZE) { + error_setg(errp, "export name too long to send to server"); + goto error; + } s->tlscredsid = g_strdup(qemu_opt_get(opts, "tls-creds")); if (s->tlscredsid) { @@ -1849,6 +1853,11 @@ static int nbd_process_options(BlockDriverState *bs, QDict *options, } s->x_dirty_bitmap = g_strdup(qemu_opt_get(opts, "x-dirty-bitmap")); + if (s->x_dirty_bitmap && strlen(s->x_dirty_bitmap) > NBD_MAX_STRING_SIZE) { + error_setg(errp, "x-dirty-bitmap query too long to send to server"); + goto error; + } + s->reconnect_delay = qemu_opt_get_number(opts, "reconnect-delay", 0); ret = 0; @@ -1859,6 +1868,7 @@ static int nbd_process_options(BlockDriverState *bs, QDict *options, qapi_free_SocketAddress(s->saddr); g_free(s->export); g_free(s->tlscredsid); + g_free(s->x_dirty_bitmap); } qemu_opts_del(opts); return ret; |