Commit 9f1f264e authored by Peter Maydell's avatar Peter Maydell
Browse files

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: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 77c9e078 5c86bdf1
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -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);
    }
}
+13 −8
Original line number Diff line number Diff line
@@ -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,18 +1997,22 @@ 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),
        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),
        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),
        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),
        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';
    }
}

static char *nbd_dirname(BlockDriverState *bs, Error **errp)
+20 −3
Original line number Diff line number Diff line
@@ -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);
+4 −0
Original line number Diff line number Diff line
@@ -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' }" \
+2 −0
Original line number Diff line number Diff line
@@ -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"}}
Loading