Commit 325b8b75d5 for qemu.org

commit 325b8b75d508468f3d443673017acb0eba08e844
Author: Eric Blake <eblake@redhat.com>
Date:   Tue Nov 10 09:54:01 2026 -0600

    nbd/server: Reject rather than assert on non-compliant NBD_OPT_SET_META_CONTEXT

    The NBD protocol says that NBD_OPT_{LIST,SET}_META_CONTEXT sends
    several lengths that must be consistent: an overall option reply
    length, then a series of smaller lengths/data pairs representing the
    export name and zero or more context names. If the smaller lengths
    within the payload do not add up to the larger value, the client has
    sent garbage bytes that will trigger the server's parse of the
    client's next option to be out of sync.  However, QEMU was dying with
    an assertion failure rather than diagnosing the issue, which a
    malicious client can then exploit to mount a denial-of-service attack
    against QEMU as the NBD server.

    As with several other recent NBD protocol violations, the likelihood
    of this attack can be reduced by using TLS and x509 certs to reject
    unwanted clients (a "trusted" client can still trigger the problem,
    but you first have to compromise the trusted client into sending
    arbitrary traffic).

    Fixes: CVE-2026-125683
    Fixes: e7b1948d51 ("nbd: BLOCK_STATUS for standard get_block_status function: server part", v2.12.0)
    Reported-by: TonySD via https://gitlab.com/qemu-project/qemu/-/work_items/4843
    CC: qemu-stable@nongnu.org
    Signed-off-by: Eric Blake <eblake@redhat.com>
    Message-ID: <20261110155356.1520433-11-eblake@redhat.com>
    Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
    Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

diff --git a/nbd/server.c b/nbd/server.c
index 8a01c27de0..8c45f9fc43 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -1095,6 +1095,11 @@ nbd_negotiate_meta_queries(NBDClient *client, Error **errp)
             }
         }
     }
+    if (client->optlen > 0) {
+        return nbd_opt_invalid(client, errp,
+                               "Inconsistent lengths in option %s",
+                               nbd_opt_lookup(client->opt));
+    }

     if (meta->base_allocation) {
         ret = nbd_negotiate_send_meta_context(client, "base:allocation",