On Sat, Jul 15, 2023 at 08:49:51PM -0500, Eric Blake wrote:
> A compliant server should not send NBD_REPLY_TYPE_BLOCK_STATUS unless
> we successfully negotiated a meta context.  And our default strictness
> settings refuse to let us send NBD_CMD_BLOCK_STATUS unless we
> negotiated a meta context.  But when you mix non-default settings
> (using nbd_set_strict to disable STRICT_COMMANDS) to send a block
> status without having negotiated it, coupled with a non-compliant
> server that responds with status anyways, we can then hit the
> assertion failure where h->meta_valid is not set during the
> REPLY.CHUNK_REPLY.RECV_BS_ENTRIES state.
> 
> Demonstration of the assertion failure can be done with a quick patch
> to nbdkit (here, on top of v1.35.6):
> 
> | diff --git i/server/protocol.c w/server/protocol.c
> | index cb530e65..6b115d99 100644
> | --- i/server/protocol.c
> | +++ w/server/protocol.c
> | @@ -190,7 +190,7 @@ validate_request (uint16_t cmd, uint16_t flags, 
> uint64_t offset, uint32_t count,
> |    }
> |
> |    /* Block status allowed? */
> | -  if (cmd == NBD_CMD_BLOCK_STATUS) {
> | +  if (cmd == NBD_CMD_BLOCK_STATUS && 0) {
> |      if (!conn->structured_replies) {
> |        nbdkit_error ("invalid request: "
> |                      "%s: structured replies was not negotiated",
> | @@ -536,7 +536,7 @@ send_structured_reply_block_status (uint64_t cookie,
> |    size_t i;
> |    int r;
> |
> | -  assert (conn->meta_context_base_allocation);
> | +  //  assert (conn->meta_context_base_allocation);
> |    assert (cmd == NBD_CMD_BLOCK_STATUS);
> |
> |    blocks = extents_to_block_descriptors (extents, flags, count, offset,
> 
> plus this sequence:
> 
> $ patched/nbdkit memory 1M
> $ ./run nbdsh --opt-mode -u nbd://localhost
> nbd> h.set_request_meta_context(False)
> nbd> h.set_export_name('a')
> nbd> def c(arg):
> ...   pass
> ...
> nbd> h.opt_set_meta_context_queries(['base:allocation'], c)
> 1
> nbd> h.set_export_name('')
> nbd> h.opt_go()
> nbd> h.set_strict_mode(0)
> nbd> h.block_status(1024*1024, 0, c)
> nbdsh: generator/states-reply-chunk.c:425: 
> enter_STATE_REPLY_CHUNK_REPLY_RECV_BS_ENTRIES: Assertion `h->meta_valid' 
> failed.
> Aborted (core dumped)
> 
> As this is not a typical setup, and is trivially avoided by sticking
> to default settings (or more safely, by using TLS connections to
> trusted servers that don't reply to a spurious block status call),
> this did not warrant a CVE.  However, since it is a case where a
> server's reply can prompt a libnbd denial of service crash, I will be
> sending a security announcement and upcoming patch be to the
> libnbd-security man page once backports are in place.
> 
> Fixes: 55b09667 ("api: Fix nbd_can_meta_context if NBD_OPT_SET_META_CONTEXT 
> fails", v1.15.3)
> Signed-off-by: Eric Blake <ebl...@redhat.com>
> ---
>  generator/states-reply-chunk.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/generator/states-reply-chunk.c b/generator/states-reply-chunk.c
> index 02c65414..26b8a6b0 100644
> --- a/generator/states-reply-chunk.c
> +++ b/generator/states-reply-chunk.c
> @@ -101,6 +101,7 @@  REPLY.CHUNK_REPLY.START:
> 
>    case NBD_REPLY_TYPE_BLOCK_STATUS:
>      if (cmd->type != NBD_CMD_BLOCK_STATUS ||
> +        !h->meta_valid || h->meta_contexts.len == 0 ||
>          length < 12 || ((length-4) & 7) != 0)
>        goto resync;
>      assert (CALLBACK_IS_NOT_NULL (cmd->cb.fn.extent));
> -- 
> 2.41.0

Thanks.  I think this is worth a note in docs/libnbd-security.pod too.

The pipeline failed after you pushed this:

https://gitlab.com/nbdkit/libnbd/-/pipelines/932589424

but I think it's an unrelated OCaml failure.  I'll take a proper look
at it tomorrow.

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-top is 'top' for virtual machines.  Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://people.redhat.com/~rjones/virt-top
_______________________________________________
Libguestfs mailing list
Libguestfs@redhat.com
https://listman.redhat.com/mailman/listinfo/libguestfs

Reply via email to