qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Eric Blake <eblake@redhat.com>
To: Alex Bligh <alex@alex.org.uk>
Cc: "qemu-devel@nongnu.org" <qemu-devel@nongnu.org>,
	Paolo Bonzini <pbonzini@redhat.com>
Subject: Re: [Qemu-devel] [PATCH 12/18] nbd: Less allocation during NBD_OPT_LIST
Date: Sat, 9 Apr 2016 16:24:41 -0600	[thread overview]
Message-ID: <57098129.9000101@redhat.com> (raw)
In-Reply-To: <F8CDA4A3-B1CA-4E84-B52C-C550E74094E6@alex.org.uk>

[-- Attachment #1: Type: text/plain, Size: 4951 bytes --]

On 04/09/2016 04:41 AM, Alex Bligh wrote:
> 
> On 8 Apr 2016, at 23:05, Eric Blake <eblake@redhat.com> wrote:
> 
>> Since we know that the maximum name we are willing to accept
>> is small enough to stack-allocate, rework the iteration over
>> NBD_OPT_LIST responses to reuse a stack buffer rather than
>> allocating every time.  Furthermore, we don't even have to
>> allocate if we know the server's length doesn't match what
>> we are searching for.
>>
>> Not fixed here: Upstream NBD Protocol recently added this
>> clarification:
>> https://github.com/yoe/nbd/blob/18918eb/doc/proto.md#conventions
>>
>> Where this document refers to a string, then unless otherwise
>> stated, that string is a sequence of UTF-8 code points, which
>> is not NUL terminated, MUST NOT contain NUL characters, SHOULD
>> be no longer than 256 bytes and MUST be no longer than 4096
>> bytes. This applies to export names and error messages (amongst
>> others).
>>
>> To be fully compliant to that, we need to bump our export name
>> limit from 255 to at least 256, and need to decide whether we
>> can bump it higher (bumping it all the way to 4096 is annoying
>> in that we could no longer safely stack-allocate a worst-case
>> string, so we may still want to take the leeway offered by SHOULD
>> to force a reasonable smaller limit).
> 
> Is there a limit in qemu-world to safe stack allocation? I thought
> that was (in general) only a kernel consideration? (probably my
> ignorance here).

Even in user space apps, any stack allocation larger than 4096 bytes
risks skipping over the guard page on Windows, which makes the
difference in whether you get a SIGSEGV (good) or a hard process kill
(bad).  We're slowly getting qemu to the point where it will compile
with gcc's options go guarantee that no one function requires more than
4k stack.

> 
> Otherwise:
> 
> 
> Reviewed-by: Alex Bligh <alex@alex.org.uk>
> 

And continuing from the things I mentioned in the other mail regarding
export name limits...

>> -    return 1;
>> +
>> +    if (len < sizeof(namelen) || len > NBD_MAX_BUFFER_SIZE) {
>> +        error_setg(errp, "incorrect option length %"PRIu32, len);
>> +        return -1;
>> +    }

This is a case of a faulty server stream (whether evil server, or MitM,
or whatever else...); if the packet wasn't big enough to include
namelen, or if the message size is larger than 32M, the stream is
considered corrupt to the point that it is no longer worth talking to
the server (hence, the return -1).

>> +    if (read_sync(ioc, &namelen, sizeof(namelen)) != sizeof(namelen)) {
>> +        error_setg(errp, "failed to read option name length");
>> +        return -1;
>> +    }

Likewise, anywhere we fail to read the server stream (most often due to
stream disconnect causing EOF), returning -1 is fine because we can't
recover anyway.

>> +    namelen = be32_to_cpu(namelen);
>> +    len -= sizeof(namelen);
>> +    if (len < namelen) {
>> +        error_setg(errp, "incorrect option name length");
>> +        return -1;
>> +    }

Likewise, if the server gives a namelen that would read beyond the
bounds of the overall packet length, the server can't be trusted for
anything else.

>> +    if (namelen != strlen(want)) {
>> +        if (drop_sync(ioc, len) != len) {
>> +            error_setg(errp, "failed to skip export name with wrong length");
>> +            return -1;
>> +        }
>> +        return 2;
>> +    }

While this gracefully handles any remaining string size, even up to
qemu's NBD_MAX_BUFFER_SIZE (32M), well beyond the required 256 or
recommended 4096 of the protocol.

>> +
>> +    assert(namelen < sizeof(name));
>> +    if (read_sync(ioc, name, namelen) != namelen) {
>> +        error_setg(errp, "failed to read export name");
>> +        return -1;
>> +    }
>> +    name[namelen] = '\0';
>> +    len -= namelen;
>> +    if (drop_sync(ioc, len) != len) {
>> +        error_setg(errp, "failed to read export description");
>> +        return -1;
>> +    }
>> +    return strcmp(name, want) == 0 ? 3 : 2;

So with this patch, I've worked it into allowing any string sizes from
the server, while focusing only on the strings that match the length of
the name requested by the client; now the audit proceeds to find out
whether letting the client request a name longer than 255 makes sense,
but at least this part of the client/server interaction is safe, and
ready for a later patch to bump the size of the #define for max name
length, unless bumping it too large makes the local buf[] exceed
preferred stack size.

[It's also interesting to note that once the NBD_OPT_GO code is live and
supported by more servers, we won't even be hitting this section of
NBD_OPT_INFO code in the qemu client]

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

  reply	other threads:[~2016-04-09 22:24 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-08 22:05 [Qemu-devel] [RFC PATCH 00/18] NBD protocol additions Eric Blake
2016-04-08 22:05 ` [Qemu-devel] [PATCH 01/18] nbd: Don't kill server on client that doesn't request TLS Eric Blake
2016-04-09 10:28   ` Alex Bligh
2016-04-08 22:05 ` [Qemu-devel] [PATCH 02/18] nbd: Don't fail handshake on NBD_OPT_LIST descriptions Eric Blake
2016-04-09 10:30   ` Alex Bligh
2016-04-08 22:05 ` [Qemu-devel] [PATCH 03/18] nbd: More debug typo fixes, use correct formats Eric Blake
2016-04-09 10:30   ` Alex Bligh
2016-04-08 22:05 ` [Qemu-devel] [PATCH 04/18] nbd: Detect servers that send unexpected error values Eric Blake
2016-04-09 10:31   ` Alex Bligh
2016-04-08 22:05 ` [Qemu-devel] [PATCH 05/18] nbd: Reject unknown request flags Eric Blake
2016-04-09 10:32   ` Alex Bligh
2016-04-08 22:05 ` [Qemu-devel] [PATCH 06/18] nbd: Avoid magic number for NBD max name size Eric Blake
2016-04-09 10:35   ` Alex Bligh
2016-04-09 22:07     ` Eric Blake
2016-04-08 22:05 ` [Qemu-devel] [PATCH 07/18] nbd: Treat flags vs. command type as separate fields Eric Blake
2016-04-09 10:37   ` Alex Bligh
2016-04-08 22:05 ` [Qemu-devel] [PATCH 08/18] nbd: Limit nbdflags to 16 bits Eric Blake
2016-04-09 10:37   ` Alex Bligh
2016-04-08 22:05 ` [Qemu-devel] [PATCH 09/18] nbd: Share common reply-sending code in server Eric Blake
2016-04-09 10:38   ` Alex Bligh
2016-04-08 22:05 ` [Qemu-devel] [PATCH 10/18] nbd: Share common option-sending code in client Eric Blake
2016-04-09 10:38   ` Alex Bligh
2016-04-08 22:05 ` [Qemu-devel] [PATCH 11/18] nbd: Let client skip portions of server reply Eric Blake
2016-04-09 10:39   ` Alex Bligh
2016-04-08 22:05 ` [Qemu-devel] [PATCH 12/18] nbd: Less allocation during NBD_OPT_LIST Eric Blake
2016-04-09 10:41   ` Alex Bligh
2016-04-09 22:24     ` Eric Blake [this message]
2016-04-08 22:05 ` [Qemu-devel] [PATCH 13/18] nbd: Support shorter handshake Eric Blake
2016-04-09 10:42   ` Alex Bligh
2016-04-09 22:27     ` Eric Blake
2016-04-08 22:05 ` [Qemu-devel] [PATCH 14/18] nbd: Implement NBD_OPT_GO on client Eric Blake
2016-04-09 10:47   ` Alex Bligh
2016-04-09 22:38     ` Eric Blake
2016-04-08 22:05 ` [Qemu-devel] [PATCH 15/18] nbd: Implement NBD_OPT_GO on server Eric Blake
2016-04-09 10:48   ` Alex Bligh
2016-04-08 22:05 ` [Qemu-devel] [PATCH 16/18] nbd: Support NBD_CMD_CLOSE Eric Blake
2016-04-09 10:50   ` Alex Bligh
2016-04-09 23:12     ` Eric Blake
2016-04-10  5:28       ` Alex Bligh
2016-04-08 22:05 ` [Qemu-devel] [RFC PATCH 17/18] nbd: Implement NBD_CMD_WRITE_ZEROES on server Eric Blake
2016-04-09  9:39   ` Pavel Borzenkov
2016-04-09 10:54   ` Alex Bligh
2016-04-08 22:05 ` [Qemu-devel] [RFC PATCH 18/18] nbd: Implement NBD_CMD_WRITE_ZEROES on client Eric Blake
2016-04-09 10:57   ` Alex Bligh
2016-04-09 11:52     ` Pavel Borzenkov
2016-04-09 23:17     ` Eric Blake
2016-04-10  5:27       ` Alex Bligh
2016-04-09 10:21 ` [Qemu-devel] [Nbd] [RFC PATCH 00/18] NBD protocol additions Wouter Verhelst

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=57098129.9000101@redhat.com \
    --to=eblake@redhat.com \
    --cc=alex@alex.org.uk \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).