From 7ed83d1436501e931246c580c4db106f372c2b42 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Wed, 18 Sep 2019 20:55:49 -0500 Subject: [PATCH] server: Fix back-to-back SET_META_CONTEXT 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 client that requests block status in spite of no response to 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 --- 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.11.4.GIT