Commit e682c0e570 for qemu.org
commit e682c0e570179bd7fa01ea896358a8cdad196a3b
Author: Eric Blake <eblake@redhat.com>
Date: Tue Nov 10 09:54:02 2026 -0600
iotests: Add another nbd-robustness test
Convert the proof of concept test by TonySD into another case of the
iotest. This is yet another instance where a hard-coded exchange is
easier than forcing libnbd into producing an exchange that violates
the protocol. Swapping the order with the previous patch shows the
assertion failure that was previously reachable.
Based-on: https://gitlab.com/qemu-project/qemu/-/work_items/4843
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-ID: <20261110155356.1520433-12-eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
diff --git a/tests/qemu-iotests/tests/nbd-robustness b/tests/qemu-iotests/tests/nbd-robustness
index fe61a83925..410dfca04e 100755
--- a/tests/qemu-iotests/tests/nbd-robustness
+++ b/tests/qemu-iotests/tests/nbd-robustness
@@ -21,6 +21,7 @@ NBD_MAGIC_REPLY = 0x0003e889045565a9 # Reply magic
NBD_MAGIC_EXT_REPLY = 0x6e8a278c # Structured reply magic
NBD_FLAG_C_FIXED_NEWSTYLE = 0x1
NBD_OPT_GO = 7
+NBD_OPT_STRUCTURED_REPLY = 8
NBD_OPT_SET_META_CONTEXT = 10
NBD_OPT_EXTENDED_HEADERS = 11
NBD_REP_ACK = 1
@@ -128,5 +129,77 @@ class TestNbdRobustness(iotests.QMPTestCase):
self.assertTrue(self.vm.is_running())
+ def test_invalid_set_meta_context(self):
+ with self.run_nbd_server(nbd_sock):
+ self.add_nbd_export('n', 'r')
+
+ # Use raw socket traffic to intentionally violate NBD protocol
+ with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
+ s.connect(nbd_sock)
+ # Server sends NBDMAGIC(8) + IHAVEOPT(8) + flags(2)
+ data = self.recv_exact(s, 18)
+ magic, opt, flags = struct.unpack(">QQH", data)
+ self.assertEqual(magic, NBD_MAGIC_INIT)
+ self.assertEqual(opt, NBD_MAGIC_OPTS)
+ self.assertEqual(flags, 0x3)
+
+ # Reply with flags(4) - just fixed newstyle flag
+ s.sendall(struct.pack(">I", NBD_FLAG_C_FIXED_NEWSTYLE))
+
+ # Request NBD_OPT_STRUCTURED_REPLY, no extra payload
+ s.sendall(struct.pack(">QII", NBD_MAGIC_OPTS,
+ NBD_OPT_STRUCTURED_REPLY, 0))
+
+ # Expect successful reply:
+ # magic(8) + option(4) + reply(4) + length(4)
+ data = self.recv_exact(s, 20)
+ magic, opt, reply, length = struct.unpack(">QIII", data)
+ self.assertEqual(magic, NBD_MAGIC_REPLY)
+ self.assertEqual(opt, NBD_OPT_STRUCTURED_REPLY)
+ self.assertEqual(reply, NBD_REP_ACK)
+ self.assertEqual(length, 0)
+
+ # Request NBD_OPT_SET_META_CONTEXT with invalid length
+ # namelen(4) + str + queries(4) + {querylen(4) + str)
+ payload = struct.pack(">I", 1) + b'r'
+ payload += struct.pack(">II", 1, 1) + b'X'
+ s.sendall(struct.pack(">QII", NBD_MAGIC_OPTS,
+ NBD_OPT_SET_META_CONTEXT,
+ len(payload) + 1) + payload)
+
+ # Request NBD_OPT_GO, name but no info as payload
+ # (request is early, but does not hurt here)
+ payload = struct.pack(">I", 1) + b'r' + struct.pack(">H", 0)
+ s.sendall(struct.pack(">QII", NBD_MAGIC_OPTS, NBD_OPT_GO,
+ len(payload)) + payload)
+
+ # Expect error reply to SET_META_CONTEXT:
+ # magic(8) + option(4) + reply(4) + length(4)
+ data = self.recv_exact(s, 20)
+ magic, opt, reply, length = struct.unpack(">QIII", data)
+ self.assertEqual(magic, NBD_MAGIC_REPLY)
+ self.assertEqual(opt, NBD_OPT_SET_META_CONTEXT)
+ self.assertEqual(reply & 0x80000000, 0x80000000)
+ self.recv_exact(s, length)
+
+ # Expect early disconnect for unaligned GO. Could show up as
+ # either b'' or ConnectionResetError
+ try:
+ data = s.recv(1)
+ self.assertEqual(data, b'')
+ except ConnectionResetError:
+ pass
+
+ # Further writes must trigger an error (EPIPE / ECONNRESET)
+ with self.assertRaises((BrokenPipeError, ConnectionResetError,
+ OSError)):
+ s.sendall(b'X')
+
+ # QEMU should still be up
+ self.assertIsNone(self.vm.exitcode())
+ self.assertTrue(self.vm.is_running())
+ res = self.vm.cmd('query-status')
+ self.assertEqual(res['status'], 'running')
+
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2'])
diff --git a/tests/qemu-iotests/tests/nbd-robustness.out b/tests/qemu-iotests/tests/nbd-robustness.out
index ae1213e6f8..fbc63e62f8 100644
--- a/tests/qemu-iotests/tests/nbd-robustness.out
+++ b/tests/qemu-iotests/tests/nbd-robustness.out
@@ -1,5 +1,5 @@
-.
+..
----------------------------------------------------------------------
-Ran 1 tests
+Ran 2 tests
OK