The NBD spec says that if a client requests a 1-query SET_META_CONTEXT for context "base:allocation", then changes its mind and requests a 1-query SET_META_CONTEXT for "other:context", only the final query matters; in such a case, since we did not reply with a context the second time, the client must not call NBD_CMD_BLOCK_STATUS, and the server should fail it with EINVAL. If the client actually wants two contexts, it must request them in a 2-query SET_META_CONTEXT. However, our code didn't reset the boolean between two uses of the option, so we were not catching an invalid clients that requests block status in spite of their second SET_META_CONTEXT.
Note that there are no known clients in the wild that can actually perform this secondary SET_META_CONTEXT request; this was found by inspection. As nbdkit does not crash in this situation, I don't see the point in hacking libnbd to make it possible to become such a client. Fixes: 26455d45 Signed-off-by: Eric Blake <ebl...@redhat.com> --- server/protocol-handshake-newstyle.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/protocol-handshake-newstyle.c b/server/protocol-handshake-newstyle.c index 06fc53ad..38978c67 100644 --- a/server/protocol-handshake-newstyle.c +++ b/server/protocol-handshake-newstyle.c @@ -566,10 +566,10 @@ negotiate_handshake_newstyle_options (struct connection *conn) debug ("newstyle negotiation: %s: %s count: %d", optname, option == NBD_OPT_LIST_META_CONTEXT ? "query" : "set", nr_queries); + if (option == NBD_OPT_SET_META_CONTEXT) + conn->meta_context_base_allocation = false; if (nr_queries == 0) { - if (option == NBD_OPT_SET_META_CONTEXT) - conn->meta_context_base_allocation = false; - else /* LIST */ { + if (option == NBD_OPT_LIST_META_CONTEXT) { if (send_newstyle_option_reply_meta_context (conn, option, NBD_REP_META_CONTEXT, 0, "base:allocation") == -1) -- 2.21.0 _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs