mirror of https://github.com/xemu-project/xemu.git
NBD patches for 2020-06-09
- fix iotest 194 race - fix CVE-2020-10761: server DoS from assertion on long NBD error messages -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEccLMIrHEYCkn0vOqp6FrSiUnQ2oFAl7hH3cACgkQp6FrSiUn Q2qPwAf+Le4m5AhAv9rLT+B9LGZFdD17dd7Dqj0CBeUyfVJKD9RtmcWIoVOsnI9Z RspYZwRgbYLZQZxKjqTKq1d1BNhK/73suGklkGQC554dik9QJOsHOmkcdK4KPwSD L0UG9muBKsmwUueGQusKFLixx39IkhQgLwLdno0wLGCao2PZUd1Z+4f/QmgLhxzI /cHzqqPtM97PFjf/lPWHvAZBcQVYmsf6SNMEqrSR30Tff5Lb5vsDFlEoaoPviEWA T2Yv1AQJwKcOrMuzmzbGeAIYeqip/WzH5mC4b8ZcKeSZ0pRcG4KoJRjuKIH78D8i iA34mc+fyUoctoyLSEFNA/v5Zdde3w== =m3k2 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2020-06-09-v2' into staging NBD patches for 2020-06-09 - fix iotest 194 race - fix CVE-2020-10761: server DoS from assertion on long NBD error messages # gpg: Signature made Wed 10 Jun 2020 18:59:19 BST # gpg: using RSA key 71C2CC22B1C4602927D2F3AAA7A16B4A2527436A # gpg: Good signature from "Eric Blake <eblake@redhat.com>" [full] # gpg: aka "Eric Blake (Free Software Programmer) <ebb9@byu.net>" [full] # gpg: aka "[jpeg image of size 6874]" [full] # Primary key fingerprint: 71C2 CC22 B1C4 6029 27D2 F3AA A7A1 6B4A 2527 436A * remotes/ericb/tags/pull-nbd-2020-06-09-v2: block: Call attention to truncation of long NBD exports nbd/server: Avoid long error message assertions CVE-2020-10761 iotests: 194: wait for migration completion on target too Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
9f1f264edb
7
block.c
7
block.c
|
@ -6809,8 +6809,11 @@ void bdrv_refresh_filename(BlockDriverState *bs)
|
|||
pstrcpy(bs->filename, sizeof(bs->filename), bs->exact_filename);
|
||||
} else {
|
||||
QString *json = qobject_to_json(QOBJECT(bs->full_open_options));
|
||||
snprintf(bs->filename, sizeof(bs->filename), "json:%s",
|
||||
qstring_get_str(json));
|
||||
if (snprintf(bs->filename, sizeof(bs->filename), "json:%s",
|
||||
qstring_get_str(json)) >= sizeof(bs->filename)) {
|
||||
/* Give user a hint if we truncated things. */
|
||||
strcpy(bs->filename + sizeof(bs->filename) - 4, "...");
|
||||
}
|
||||
qobject_unref(json);
|
||||
}
|
||||
}
|
||||
|
|
21
block/nbd.c
21
block/nbd.c
|
@ -1984,6 +1984,7 @@ static void nbd_refresh_filename(BlockDriverState *bs)
|
|||
{
|
||||
BDRVNBDState *s = bs->opaque;
|
||||
const char *host = NULL, *port = NULL, *path = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
if (s->saddr->type == SOCKET_ADDRESS_TYPE_INET) {
|
||||
const InetSocketAddress *inet = &s->saddr->u.inet;
|
||||
|
@ -1996,17 +1997,21 @@ static void nbd_refresh_filename(BlockDriverState *bs)
|
|||
} /* else can't represent as pseudo-filename */
|
||||
|
||||
if (path && s->export) {
|
||||
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
|
||||
"nbd+unix:///%s?socket=%s", s->export, path);
|
||||
len = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
|
||||
"nbd+unix:///%s?socket=%s", s->export, path);
|
||||
} else if (path && !s->export) {
|
||||
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
|
||||
"nbd+unix://?socket=%s", path);
|
||||
len = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
|
||||
"nbd+unix://?socket=%s", path);
|
||||
} else if (host && s->export) {
|
||||
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
|
||||
"nbd://%s:%s/%s", host, port, s->export);
|
||||
len = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
|
||||
"nbd://%s:%s/%s", host, port, s->export);
|
||||
} else if (host && !s->export) {
|
||||
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
|
||||
"nbd://%s:%s", host, port);
|
||||
len = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
|
||||
"nbd://%s:%s", host, port);
|
||||
}
|
||||
if (len > sizeof(bs->exact_filename)) {
|
||||
/* Name is too long to represent exactly, so leave it empty. */
|
||||
bs->exact_filename[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
23
nbd/server.c
23
nbd/server.c
|
@ -217,7 +217,7 @@ nbd_negotiate_send_rep_verr(NBDClient *client, uint32_t type,
|
|||
|
||||
msg = g_strdup_vprintf(fmt, va);
|
||||
len = strlen(msg);
|
||||
assert(len < 4096);
|
||||
assert(len < NBD_MAX_STRING_SIZE);
|
||||
trace_nbd_negotiate_send_rep_err(msg);
|
||||
ret = nbd_negotiate_send_rep_len(client, type, len, errp);
|
||||
if (ret < 0) {
|
||||
|
@ -231,6 +231,19 @@ nbd_negotiate_send_rep_verr(NBDClient *client, uint32_t type,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a malloc'd copy of @name suitable for use in an error reply.
|
||||
*/
|
||||
static char *
|
||||
nbd_sanitize_name(const char *name)
|
||||
{
|
||||
if (strnlen(name, 80) < 80) {
|
||||
return g_strdup(name);
|
||||
}
|
||||
/* XXX Should we also try to sanitize any control characters? */
|
||||
return g_strdup_printf("%.80s...", name);
|
||||
}
|
||||
|
||||
/* Send an error reply.
|
||||
* Return -errno on error, 0 on success. */
|
||||
static int GCC_FMT_ATTR(4, 5)
|
||||
|
@ -595,9 +608,11 @@ static int nbd_negotiate_handle_info(NBDClient *client, Error **errp)
|
|||
|
||||
exp = nbd_export_find(name);
|
||||
if (!exp) {
|
||||
g_autofree char *sane_name = nbd_sanitize_name(name);
|
||||
|
||||
return nbd_negotiate_send_rep_err(client, NBD_REP_ERR_UNKNOWN,
|
||||
errp, "export '%s' not present",
|
||||
name);
|
||||
sane_name);
|
||||
}
|
||||
|
||||
/* Don't bother sending NBD_INFO_NAME unless client requested it */
|
||||
|
@ -995,8 +1010,10 @@ static int nbd_negotiate_meta_queries(NBDClient *client,
|
|||
|
||||
meta->exp = nbd_export_find(export_name);
|
||||
if (meta->exp == NULL) {
|
||||
g_autofree char *sane_name = nbd_sanitize_name(export_name);
|
||||
|
||||
return nbd_opt_drop(client, NBD_REP_ERR_UNKNOWN, errp,
|
||||
"export '%s' not present", export_name);
|
||||
"export '%s' not present", sane_name);
|
||||
}
|
||||
|
||||
ret = nbd_opt_read(client, &nb_queries, sizeof(nb_queries), errp);
|
||||
|
|
|
@ -58,6 +58,10 @@ _send_qemu_cmd $QEMU_HANDLE \
|
|||
$QEMU_IO_PROG -f raw -c quit \
|
||||
"nbd+unix:///no_such_export?socket=$SOCK_DIR/nbd" 2>&1 \
|
||||
| _filter_qemu_io | _filter_nbd
|
||||
# Likewise, with longest possible name permitted in NBD protocol
|
||||
$QEMU_IO_PROG -f raw -c quit \
|
||||
"nbd+unix:///$(printf %4096d 1 | tr ' ' a)?socket=$SOCK_DIR/nbd" 2>&1 \
|
||||
| _filter_qemu_io | _filter_nbd | sed 's/aaaa*aa/aa--aa/'
|
||||
|
||||
_send_qemu_cmd $QEMU_HANDLE \
|
||||
"{ 'execute': 'quit' }" \
|
||||
|
|
|
@ -5,6 +5,8 @@ QA output created by 143
|
|||
{"return": {}}
|
||||
qemu-io: can't open device nbd+unix:///no_such_export?socket=SOCK_DIR/nbd: Requested export not available
|
||||
server reported: export 'no_such_export' not present
|
||||
qemu-io: can't open device nbd+unix:///aa--aa1?socket=SOCK_DIR/nbd: Requested export not available
|
||||
server reported: export 'aa--aa...' not present
|
||||
{ 'execute': 'quit' }
|
||||
{"return": {}}
|
||||
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
|
||||
|
|
|
@ -87,4 +87,14 @@ with iotests.FilePath('source.img') as source_img_path, \
|
|||
iotests.log(dest_vm.qmp('nbd-server-stop'))
|
||||
break
|
||||
|
||||
iotests.log('Wait for migration completion on target...')
|
||||
migr_events = (('MIGRATION', {'data': {'status': 'completed'}}),
|
||||
('MIGRATION', {'data': {'status': 'failed'}}))
|
||||
event = dest_vm.events_wait(migr_events)
|
||||
iotests.log(event, filters=[iotests.filter_qmp_event])
|
||||
|
||||
iotests.log('Check bitmaps on source:')
|
||||
iotests.log(source_vm.qmp('query-block')['return'][0]['dirty-bitmaps'])
|
||||
|
||||
iotests.log('Check bitmaps on target:')
|
||||
iotests.log(dest_vm.qmp('query-block')['return'][0]['dirty-bitmaps'])
|
||||
|
|
|
@ -21,4 +21,9 @@ Gracefully ending the `drive-mirror` job on source...
|
|||
{"data": {"device": "mirror-job0", "len": 1073741824, "offset": 1073741824, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
|
||||
Stopping the NBD server on destination...
|
||||
{"return": {}}
|
||||
Wait for migration completion on target...
|
||||
{"data": {"status": "completed"}, "event": "MIGRATION", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
|
||||
Check bitmaps on source:
|
||||
[{"busy": false, "count": 0, "granularity": 65536, "name": "bitmap0", "persistent": false, "recording": true, "status": "active"}]
|
||||
Check bitmaps on target:
|
||||
[{"busy": false, "count": 0, "granularity": 65536, "name": "bitmap0", "persistent": false, "recording": true, "status": "active"}]
|
||||
|
|
Loading…
Reference in New Issue