* [PATCH for-11.2 v2 0/3] Avoid low-severity NBD denial-of-service attack
@ 2026-11-07 22:54 Eric Blake
2026-11-07 22:54 ` [PATCH v2 1/3] docs: Mention security considerations for NBD Eric Blake
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Eric Blake @ 2026-11-07 22:54 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, berrange, qemu-block
AI found a way to trip an assertion failure by sending a particular
BLOCK_STATUS command in violation of the NBD protocol, documented at
https://gitlab.com/qemu-project/qemu/-/work_items/3796 and again at
https://gitlab.com/qemu-project/qemu/-/work_items/4091. Since the
attack can be trivially avoided by using TLS + x509 certificates to
avoid untrusted clients avoiding the protocol non-compliance, I'm
posting the patch now, rather than waiting for a CVE assignment, per
https://www.qemu.org/contribute/security-process/
v1: https://lists.nongnu.org/archive/html/qemu-devel/2026-11/msg01615.html
- since then, adjust wording based on Dan's feedback
- add the NBD fix and a unit test
Eric Blake (3):
docs: Mention security considerations for NBD
nbd/server: Reject rather than assert on non-compliant BLOCK_STATUS
iotests: Add new nbd-robustness test
docs/system/security.rst | 21 +++
nbd/server.c | 4 +-
tests/qemu-iotests/tests/nbd-robustness | 137 ++++++++++++++++++++
tests/qemu-iotests/tests/nbd-robustness.out | 5 +
4 files changed, 165 insertions(+), 2 deletions(-)
create mode 100755 tests/qemu-iotests/tests/nbd-robustness
create mode 100644 tests/qemu-iotests/tests/nbd-robustness.out
--
2.56.0
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH v2 1/3] docs: Mention security considerations for NBD 2026-11-07 22:54 [PATCH for-11.2 v2 0/3] Avoid low-severity NBD denial-of-service attack Eric Blake @ 2026-11-07 22:54 ` Eric Blake 2026-11-09 15:58 ` Stefan Hajnoczi 2026-11-07 22:54 ` [PATCH v2 2/3] nbd/server: Reject rather than assert on non-compliant BLOCK_STATUS Eric Blake 2026-11-07 22:54 ` [PATCH v2 3/3] iotests: Add new nbd-robustness test Eric Blake 2 siblings, 1 reply; 12+ messages in thread From: Eric Blake @ 2026-11-07 22:54 UTC (permalink / raw) To: qemu-devel; +Cc: qemu-stable, berrange, qemu-block, Pierrick Bouvier Document a policy that NBD connections should strongly consider using TLS and x509 certificates to filter out untrusted clients. If a malicious server or client can trigger a QEMU assertion failure on a plaintext connection, but can be trivially mitigated by enabling TLS to weed out untrusted partners that would violate the protocol in the first place, then I prefer to treat the bug as a lower-priority issue, which our policy states can be fixed without an embargo. Signed-off-by: Eric Blake <eblake@redhat.com> --- docs/system/security.rst | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docs/system/security.rst b/docs/system/security.rst index e211fdd2344..7b422d51472 100644 --- a/docs/system/security.rst +++ b/docs/system/security.rst @@ -320,3 +320,24 @@ encryption and authorization control policy on client connections. In summary, the monitor console is considered a privileged control interface to QEMU and as such should only be made accessible to a trusted management application or user. + +Block device network protocols (NBD, NFS, etc.) +''''''''''''''''''''''''''''''''''''''''''''''' + +When using QEMU to access remote storage over a network (such as QEMU +acting as an NBD or NFS client) or to provide remote storage access +(such as QEMU acting as an NBD server), it is important to realize +that an unencrypted connection can allow an external process a +potential attack vector over the network port. When possible, QEMU +should be configured to require TLS to prevent a man-in-the-middle +attack, as well as use x509 client certificates with the +tls-creds-x509 object set with 'verify-peer=on' to check that the peer +is allowed to connect. It may also be worth using 'tls-authz' to +filter which certificates are allowed if the CA issues certs more +broadly. + +Proper hardening of network connections can prevent the use of +untrusted clients, and is therefore a factor when considering whether +a malicious network partner that intentionally violates the +communication protocol to trigger a QEMU bug can be treated as a lower +priority bug. -- 2.56.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/3] docs: Mention security considerations for NBD 2026-11-07 22:54 ` [PATCH v2 1/3] docs: Mention security considerations for NBD Eric Blake @ 2026-11-09 15:58 ` Stefan Hajnoczi 2026-11-09 20:48 ` Eric Blake 0 siblings, 1 reply; 12+ messages in thread From: Stefan Hajnoczi @ 2026-11-09 15:58 UTC (permalink / raw) To: Eric Blake Cc: qemu-devel, qemu-stable, berrange, qemu-block, Pierrick Bouvier On Sat, Nov 07, 2026 at 04:54:36PM -0600, Eric Blake wrote: > +Proper hardening of network connections can prevent the use of > +untrusted clients, and is therefore a factor when considering whether > +a malicious network partner that intentionally violates the > +communication protocol to trigger a QEMU bug can be treated as a lower > +priority bug. IMO there is no such thing as a trusted client - QEMU needs to validate all inputs. When a client is authorized to use a resource (e.g. an NBD export) it can still be rogue and trigger a Denial of Service that affects the guest or other clients. Did you add this because there was no CVE assigned yet? Maybe you can remove this since a CVE has been assigned? Stefan ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/3] docs: Mention security considerations for NBD 2026-11-09 15:58 ` Stefan Hajnoczi @ 2026-11-09 20:48 ` Eric Blake 2026-11-10 8:48 ` Daniel P. Berrangé 0 siblings, 1 reply; 12+ messages in thread From: Eric Blake @ 2026-11-09 20:48 UTC (permalink / raw) To: Stefan Hajnoczi Cc: qemu-devel, qemu-stable, berrange, qemu-block, Pierrick Bouvier On Mon, Nov 09, 2026 at 08:58:47AM -0700, Stefan Hajnoczi wrote: > On Sat, Nov 07, 2026 at 04:54:36PM -0600, Eric Blake wrote: > > +Proper hardening of network connections can prevent the use of > > +untrusted clients, and is therefore a factor when considering whether > > +a malicious network partner that intentionally violates the > > +communication protocol to trigger a QEMU bug can be treated as a lower > > +priority bug. > > IMO there is no such thing as a trusted client - QEMU needs to validate > all inputs. When a client is authorized to use a resource (e.g. an NBD > export) it can still be rogue and trigger a Denial of Service that > affects the guest or other clients. > > Did you add this because there was no CVE assigned yet? Maybe you can > remove this since a CVE has been assigned? I've got at least one other bug pending that I'm about to lift confidentiality on, in the same boat where TLS prevents untrusted client behavior, but where I don't have a CVE number yet. But I agree that since we don't fully control even a trusted client process, ANY flaw in the client that allows the client to start sending non-compliant data over the wire can then be escalated further into an attack on QEMU, despite QEMU minimizing the risk of such attacks by first filtering out obvious untrusted clients. I'm trying to figure out the best balance of wording for that. In the CVSS scoring system [1], you are arguing (and I agree) that the CVSS-B base score is unchanged by whether or not TLS was in use (we don't control the remote client; if the remote client can send non-compliant bytes over the wire, QEMU will assert). However, the environmental metrics of CVSS-BE cover Attack Complexity (AC) and Attack Requirements (AR) that consider how hard it is to get the client to be non-compliant in the first place. Once attack chaining is involved, the risk to QEMU is less than if the attacker does not first have to compromise a trusted client into sending non-compliant bytes. [1] https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator Maybe the solution is as simple as rewording "trusted client" into "authenticated client", to emphasize that while any client misbehavior that can crash QEMU is still likely to be a CVE, the authentication aspect affects the Environmental analysis which in turn reduces the overall CVSS-BE rating of the attack. -- Eric Blake, Principal Software Engineer Red Hat, Inc. Virtualization: qemu.org | libguestfs.org ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/3] docs: Mention security considerations for NBD 2026-11-09 20:48 ` Eric Blake @ 2026-11-10 8:48 ` Daniel P. Berrangé 0 siblings, 0 replies; 12+ messages in thread From: Daniel P. Berrangé @ 2026-11-10 8:48 UTC (permalink / raw) To: Eric Blake Cc: Stefan Hajnoczi, qemu-devel, qemu-stable, qemu-block, Pierrick Bouvier On Mon, Nov 09, 2026 at 02:48:18PM -0600, Eric Blake wrote: > On Mon, Nov 09, 2026 at 08:58:47AM -0700, Stefan Hajnoczi wrote: > > On Sat, Nov 07, 2026 at 04:54:36PM -0600, Eric Blake wrote: > > > +Proper hardening of network connections can prevent the use of > > > +untrusted clients, and is therefore a factor when considering whether > > > +a malicious network partner that intentionally violates the > > > +communication protocol to trigger a QEMU bug can be treated as a lower > > > +priority bug. > > > > IMO there is no such thing as a trusted client - QEMU needs to validate > > all inputs. When a client is authorized to use a resource (e.g. an NBD > > export) it can still be rogue and trigger a Denial of Service that > > affects the guest or other clients. > > > > > Did you add this because there was no CVE assigned yet? Maybe you can > > remove this since a CVE has been assigned? > > I've got at least one other bug pending that I'm about to lift > confidentiality on, in the same boat where TLS prevents untrusted > client behavior, but where I don't have a CVE number yet. But I agree > that since we don't fully control even a trusted client process, ANY > flaw in the client that allows the client to start sending > non-compliant data over the wire can then be escalated further into an > attack on QEMU, despite QEMU minimizing the risk of such attacks by > first filtering out obvious untrusted clients. > > I'm trying to figure out the best balance of wording for that. In the > CVSS scoring system [1], you are arguing (and I agree) that the CVSS-B > base score is unchanged by whether or not TLS was in use (we don't > control the remote client; if the remote client can send non-compliant > bytes over the wire, QEMU will assert). However, the environmental > metrics of CVSS-BE cover Attack Complexity (AC) and Attack > Requirements (AR) that consider how hard it is to get the client to be > non-compliant in the first place. Once attack chaining is involved, > the risk to QEMU is less than if the attacker does not first have to > compromise a trusted client into sending non-compliant bytes. > > [1] https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator > > Maybe the solution is as simple as rewording "trusted client" into > "authenticated client", to emphasize that while any client misbehavior > that can crash QEMU is still likely to be a CVE, the authentication > aspect affects the Environmental analysis which in turn reduces the > overall CVSS-BE rating of the attack. Yes, using 'authenticated client' is a better term, as that is more of a clear "fact", where as "trusted client" can mean many different things in different people & scenarios With regards, Daniel -- |: https://berrange.com ~~ https://hachyderm.io/@berrange :| |: https://libvirt.org ~~ https://entangle-photo.org :| |: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :| ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 2/3] nbd/server: Reject rather than assert on non-compliant BLOCK_STATUS 2026-11-07 22:54 [PATCH for-11.2 v2 0/3] Avoid low-severity NBD denial-of-service attack Eric Blake 2026-11-07 22:54 ` [PATCH v2 1/3] docs: Mention security considerations for NBD Eric Blake @ 2026-11-07 22:54 ` Eric Blake 2026-11-09 13:57 ` Eric Blake ` (2 more replies) 2026-11-07 22:54 ` [PATCH v2 3/3] iotests: Add new nbd-robustness test Eric Blake 2 siblings, 3 replies; 12+ messages in thread From: Eric Blake @ 2026-11-07 22:54 UTC (permalink / raw) To: qemu-devel Cc: qemu-stable, berrange, qemu-block, Feifan Qian, Haotian Jiang, Vladimir Sementsov-Ogievskiy The NBD spec is clear that a client must not send NBD_BLOCK_STATUS requests to a server if it did not negotiate any metacontexts with NBD_OPT_SET_META_CONTEXT. However, if the non-compliant client uses NBD_OPT_EXTENDED_HEADERS and then passes in the relatively new NBD_CMD_FLAG_PAYLOAD_LEN flag alongside an inappropriate block status request, this was enough to trigger an assertion in qemu. If you do not use recommended practice to prevent untrusted clients from connecting to QEMU's NBD server, then you are at risk of a denial of service attack from a rogue client. Per our stated policy on flaws triggered by network connections, this is considered a low-severity security flaw, since it is trivial to avoid by using proper configuration of TLS and x509 certificate authorization to reject rogue clients; therefore, no CVE has been assigned yet. Fixes: 2dcbb11b ("nbd/server: Add FLAG_PAYLOAD support to CMD_BLOCK_STATUS", v8.2.0) Reported-by: Feifan Qian <bea1e@proton.me> Reported-by: https://gitlab.com/qemu-project/qemu/-/work_items/3796 CC: Haotian Jiang <jianghaotian.sunday@gmail.com> CC: qemu-stable@nongnu.org Signed-off-by: Eric Blake <eblake@redhat.com> --- nbd/server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nbd/server.c b/nbd/server.c index e6c47f8c2e3..bc37cbcb338 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -2584,12 +2584,12 @@ nbd_co_block_status_payload_read(NBDClient *client, NBDRequest *request, return -EINVAL; } - assert(client->contexts.exp == client->exp); nr_bitmaps = client->exp->nr_export_bitmaps; request->contexts = g_new0(NBDMetaContexts, 1); request->contexts->exp = client->exp; - if (payload_len % sizeof(uint32_t) || + if (!client->contexts.count || + payload_len % sizeof(uint32_t) || payload_len < sizeof(NBDBlockStatusPayload) || payload_len > (sizeof(NBDBlockStatusPayload) + sizeof(id) * client->contexts.count)) { -- 2.56.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 2/3] nbd/server: Reject rather than assert on non-compliant BLOCK_STATUS 2026-11-07 22:54 ` [PATCH v2 2/3] nbd/server: Reject rather than assert on non-compliant BLOCK_STATUS Eric Blake @ 2026-11-09 13:57 ` Eric Blake 2026-11-09 15:45 ` Stefan Hajnoczi 2026-11-09 15:51 ` Stefan Hajnoczi 2 siblings, 0 replies; 12+ messages in thread From: Eric Blake @ 2026-11-09 13:57 UTC (permalink / raw) To: qemu-devel Cc: qemu-stable, berrange, qemu-block, Feifan Qian, Haotian Jiang, Vladimir Sementsov-Ogievskiy On Sat, Nov 07, 2026 at 04:54:37PM -0600, Eric Blake wrote: > The NBD spec is clear that a client must not send NBD_BLOCK_STATUS > requests to a server if it did not negotiate any metacontexts with > NBD_OPT_SET_META_CONTEXT. However, if the non-compliant client uses > NBD_OPT_EXTENDED_HEADERS and then passes in the relatively new > NBD_CMD_FLAG_PAYLOAD_LEN flag alongside an inappropriate block status > request, this was enough to trigger an assertion in qemu. > > If you do not use recommended practice to prevent untrusted clients > from connecting to QEMU's NBD server, then you are at risk of a denial > of service attack from a rogue client. Per our stated policy on flaws > triggered by network connections, this is considered a low-severity > security flaw, since it is trivial to avoid by using proper > configuration of TLS and x509 certificate authorization to reject > rogue clients; therefore, no CVE has been assigned yet. CVE-2026-124559 has been assigned; I'll update the commit message accordingly before the pull request, if no other changes in the series are requested. > > Fixes: 2dcbb11b ("nbd/server: Add FLAG_PAYLOAD support to CMD_BLOCK_STATUS", v8.2.0) > Reported-by: Feifan Qian <bea1e@proton.me> > Reported-by: https://gitlab.com/qemu-project/qemu/-/work_items/3796 > CC: Haotian Jiang <jianghaotian.sunday@gmail.com> > CC: qemu-stable@nongnu.org > Signed-off-by: Eric Blake <eblake@redhat.com> > --- > nbd/server.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/nbd/server.c b/nbd/server.c > index e6c47f8c2e3..bc37cbcb338 100644 > --- a/nbd/server.c > +++ b/nbd/server.c > @@ -2584,12 +2584,12 @@ nbd_co_block_status_payload_read(NBDClient *client, NBDRequest *request, > return -EINVAL; > } > > - assert(client->contexts.exp == client->exp); > nr_bitmaps = client->exp->nr_export_bitmaps; > request->contexts = g_new0(NBDMetaContexts, 1); > request->contexts->exp = client->exp; > > - if (payload_len % sizeof(uint32_t) || > + if (!client->contexts.count || > + payload_len % sizeof(uint32_t) || > payload_len < sizeof(NBDBlockStatusPayload) || > payload_len > (sizeof(NBDBlockStatusPayload) + > sizeof(id) * client->contexts.count)) { > -- > 2.56.0 > > -- Eric Blake, Principal Software Engineer Red Hat, Inc. Virtualization: qemu.org | libguestfs.org ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 2/3] nbd/server: Reject rather than assert on non-compliant BLOCK_STATUS 2026-11-07 22:54 ` [PATCH v2 2/3] nbd/server: Reject rather than assert on non-compliant BLOCK_STATUS Eric Blake 2026-11-09 13:57 ` Eric Blake @ 2026-11-09 15:45 ` Stefan Hajnoczi 2026-11-09 15:51 ` Stefan Hajnoczi 2 siblings, 0 replies; 12+ messages in thread From: Stefan Hajnoczi @ 2026-11-09 15:45 UTC (permalink / raw) To: Eric Blake Cc: qemu-devel, qemu-stable, berrange, qemu-block, Feifan Qian, Haotian Jiang, Vladimir Sementsov-Ogievskiy On Sat, Nov 07, 2026 at 04:54:37PM -0600, Eric Blake wrote: > The NBD spec is clear that a client must not send NBD_BLOCK_STATUS > requests to a server if it did not negotiate any metacontexts with > NBD_OPT_SET_META_CONTEXT. However, if the non-compliant client uses > NBD_OPT_EXTENDED_HEADERS and then passes in the relatively new > NBD_CMD_FLAG_PAYLOAD_LEN flag alongside an inappropriate block status > request, this was enough to trigger an assertion in qemu. > > If you do not use recommended practice to prevent untrusted clients > from connecting to QEMU's NBD server, then you are at risk of a denial > of service attack from a rogue client. Per our stated policy on flaws > triggered by network connections, this is considered a low-severity > security flaw, since it is trivial to avoid by using proper > configuration of TLS and x509 certificate authorization to reject > rogue clients; therefore, no CVE has been assigned yet. > > Fixes: 2dcbb11b ("nbd/server: Add FLAG_PAYLOAD support to CMD_BLOCK_STATUS", v8.2.0) > Reported-by: Feifan Qian <bea1e@proton.me> > Reported-by: https://gitlab.com/qemu-project/qemu/-/work_items/3796 > CC: Haotian Jiang <jianghaotian.sunday@gmail.com> > CC: qemu-stable@nongnu.org > Signed-off-by: Eric Blake <eblake@redhat.com> > --- > nbd/server.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 2/3] nbd/server: Reject rather than assert on non-compliant BLOCK_STATUS 2026-11-07 22:54 ` [PATCH v2 2/3] nbd/server: Reject rather than assert on non-compliant BLOCK_STATUS Eric Blake 2026-11-09 13:57 ` Eric Blake 2026-11-09 15:45 ` Stefan Hajnoczi @ 2026-11-09 15:51 ` Stefan Hajnoczi 2 siblings, 0 replies; 12+ messages in thread From: Stefan Hajnoczi @ 2026-11-09 15:51 UTC (permalink / raw) To: Eric Blake Cc: qemu-devel, qemu-stable, berrange, qemu-block, Feifan Qian, Haotian Jiang, Vladimir Sementsov-Ogievskiy On Sat, Nov 07, 2026 at 04:54:37PM -0600, Eric Blake wrote: > The NBD spec is clear that a client must not send NBD_BLOCK_STATUS > requests to a server if it did not negotiate any metacontexts with > NBD_OPT_SET_META_CONTEXT. However, if the non-compliant client uses > NBD_OPT_EXTENDED_HEADERS and then passes in the relatively new > NBD_CMD_FLAG_PAYLOAD_LEN flag alongside an inappropriate block status > request, this was enough to trigger an assertion in qemu. > > If you do not use recommended practice to prevent untrusted clients > from connecting to QEMU's NBD server, then you are at risk of a denial > of service attack from a rogue client. Per our stated policy on flaws > triggered by network connections, this is considered a low-severity > security flaw, since it is trivial to avoid by using proper > configuration of TLS and x509 certificate authorization to reject > rogue clients; therefore, no CVE has been assigned yet. > > Fixes: 2dcbb11b ("nbd/server: Add FLAG_PAYLOAD support to CMD_BLOCK_STATUS", v8.2.0) > Reported-by: Feifan Qian <bea1e@proton.me> > Reported-by: https://gitlab.com/qemu-project/qemu/-/work_items/3796 > CC: Haotian Jiang <jianghaotian.sunday@gmail.com> > CC: qemu-stable@nongnu.org > Signed-off-by: Eric Blake <eblake@redhat.com> > --- > nbd/server.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 3/3] iotests: Add new nbd-robustness test 2026-11-07 22:54 [PATCH for-11.2 v2 0/3] Avoid low-severity NBD denial-of-service attack Eric Blake 2026-11-07 22:54 ` [PATCH v2 1/3] docs: Mention security considerations for NBD Eric Blake 2026-11-07 22:54 ` [PATCH v2 2/3] nbd/server: Reject rather than assert on non-compliant BLOCK_STATUS Eric Blake @ 2026-11-07 22:54 ` Eric Blake 2026-11-09 15:36 ` Stefan Hajnoczi 2 siblings, 1 reply; 12+ messages in thread From: Eric Blake @ 2026-11-07 22:54 UTC (permalink / raw) To: qemu-devel Cc: qemu-stable, berrange, qemu-block, Vladimir Sementsov-Ogievskiy, Kevin Wolf, Hanna Reitz Convert the proof of concept test by Sunday Jiang into an iotest. I tried to get libnbd to trigger the situation, but forcing a block status command when no status has been initiated is not something that libnbd is willing to do. So this results in a hard-coded sequence of bytes sent over a raw socket. 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/4091 Signed-off-by: Eric Blake <eblake@redhat.com> --- tests/qemu-iotests/tests/nbd-robustness | 137 ++++++++++++++++++++ tests/qemu-iotests/tests/nbd-robustness.out | 5 + 2 files changed, 142 insertions(+) create mode 100755 tests/qemu-iotests/tests/nbd-robustness create mode 100644 tests/qemu-iotests/tests/nbd-robustness.out diff --git a/tests/qemu-iotests/tests/nbd-robustness b/tests/qemu-iotests/tests/nbd-robustness new file mode 100755 index 00000000000..602b7060854 --- /dev/null +++ b/tests/qemu-iotests/tests/nbd-robustness @@ -0,0 +1,137 @@ +#!/usr/bin/env python3 +# group: rw auto quick +# +# Test cases for NBD robustness against malicious clients +# +# Copyright (C) 2026 Red Hat, Inc. +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import os +from contextlib import contextmanager + +import iotests +from iotests import qemu_img_create, qemu_io + +import socket +import struct + + +disk = os.path.join(iotests.test_dir, 'disk') +size = '4M' +nbd_sock = os.path.join(iotests.sock_dir, 'nbd_sock') +nbd_uri = 'nbd+unix:///{}?socket=' + nbd_sock +nbd: ModuleType + + +class TestNbdRobustness(iotests.QMPTestCase): + def setUp(self): + qemu_img_create('-f', iotests.imgfmt, disk, size) + qemu_io('-c', 'w -P 1 0 2M', '-c', 'w -P 2 2M 2M', disk) + + self.vm = iotests.VM() + self.vm.launch() + self.vm.cmd('blockdev-add', { + 'driver': 'qcow2', + 'node-name': 'n', + 'file': {'driver': 'file', 'filename': disk} + }) + + def tearDown(self): + self.vm.shutdown() + os.remove(disk) + try: + os.remove(nbd_sock) + except OSError: + pass + + @contextmanager + def run_server(self, max_connections=None): + args = { + 'addr': { + 'type': 'unix', + 'data': {'path': nbd_sock} + } + } + if max_connections is not None: + args['max-connections'] = max_connections + + self.vm.cmd('nbd-server-start', args) + yield + + self.vm.cmd('nbd-server-stop') + + def add_export(self, name, writable=None): + args = { + 'type': 'nbd', + 'id': name, + 'node-name': 'n', + 'name': name, + } + if writable is not None: + args['writable'] = writable + + self.vm.cmd('block-export-add', args) + + def test_invalid_block_status(self): + with self.run_server(): + self.add_export('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 = s.recv(18) + magic, opt, flags = struct.unpack(">QQH", data) + assert magic == 0x4e42444d41474943 + assert opt == 0x49484156454f5054 + assert flags == 0x3 + + # Reply with flags(4) - just fixed newstyle flag + s.send(struct.pack(">I", 1)) + + # Request NBD_OPT_EXTENDED_HEADERS, no extra payload + s.send(struct.pack(">QII", 0x49484156454f5054, 11, 0)) + + # Expect successful reply: + # magic(8) + option(4) + reply(4) + length(4) + data = s.recv(20) + magic, opt, reply, length = struct.unpack(">QIII", data) + assert magic == 0x3e889045565a9 + assert opt == 11 + assert reply == 1 + assert length == 0 + + # Request NBD_OPT_GO, name but no info as payload + payload = struct.pack(">I", 1) + b'r' + struct.pack(">H", 0) + s.send(struct.pack(">QII", 0x49484156454f5054, 7, len(payload)) + + payload) + + # Expect (and ignore) zero or more info packets before ack + while True: + data = s.recv(20) + magic, opt, reply, length = struct.unpack(">QIII", data) + assert magic == 0x3e889045565a9 + assert opt == 7 + payload = s.recv(length) + if reply != 3: + break + assert reply == 1 + + # Send invalid NBD_CMD_BLOCK_STATUS with payload flag. This + # violates the NBD protocol (since no context was negotiated), + # but should not crash the server. + payload = struct.pack(">QI", 0x1000, 0) + s.send(struct.pack(">IHHQQQ", 0x21e41c71, 0x20, 7, 1, 0, + len(payload)) + payload) + + # Expect a rejection. + data = s.recv(32) + magic, flags, rtype, cookie, offs, length = struct.unpack(">IHHQQQ", data) + assert magic == 0x6e8a278c + assert rtype & 0x8000 == 0x8000 + assert cookie == 1 + s.recv(length) + +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 new file mode 100644 index 00000000000..ae1213e6f86 --- /dev/null +++ b/tests/qemu-iotests/tests/nbd-robustness.out @@ -0,0 +1,5 @@ +. +---------------------------------------------------------------------- +Ran 1 tests + +OK -- 2.56.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 3/3] iotests: Add new nbd-robustness test 2026-11-07 22:54 ` [PATCH v2 3/3] iotests: Add new nbd-robustness test Eric Blake @ 2026-11-09 15:36 ` Stefan Hajnoczi 2026-11-09 16:06 ` Eric Blake 0 siblings, 1 reply; 12+ messages in thread From: Stefan Hajnoczi @ 2026-11-09 15:36 UTC (permalink / raw) To: Eric Blake Cc: qemu-devel, qemu-stable, berrange, qemu-block, Vladimir Sementsov-Ogievskiy, Kevin Wolf, Hanna Reitz On Sat, Nov 07, 2026 at 04:54:38PM -0600, Eric Blake wrote: > Convert the proof of concept test by Sunday Jiang into an iotest. I > tried to get libnbd to trigger the situation, but forcing a block > status command when no status has been initiated is not something that > libnbd is willing to do. So this results in a hard-coded sequence of > bytes sent over a raw socket. 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/4091 > Signed-off-by: Eric Blake <eblake@redhat.com> > --- > tests/qemu-iotests/tests/nbd-robustness | 137 ++++++++++++++++++++ > tests/qemu-iotests/tests/nbd-robustness.out | 5 + > 2 files changed, 142 insertions(+) > create mode 100755 tests/qemu-iotests/tests/nbd-robustness > create mode 100644 tests/qemu-iotests/tests/nbd-robustness.out > > diff --git a/tests/qemu-iotests/tests/nbd-robustness b/tests/qemu-iotests/tests/nbd-robustness > new file mode 100755 > index 00000000000..602b7060854 > --- /dev/null > +++ b/tests/qemu-iotests/tests/nbd-robustness > @@ -0,0 +1,137 @@ > +#!/usr/bin/env python3 > +# group: rw auto quick > +# > +# Test cases for NBD robustness against malicious clients > +# > +# Copyright (C) 2026 Red Hat, Inc. > +# > +# SPDX-License-Identifier: GPL-2.0-or-later > + > +import os > +from contextlib import contextmanager > + > +import iotests > +from iotests import qemu_img_create, qemu_io > + > +import socket > +import struct > + > + > +disk = os.path.join(iotests.test_dir, 'disk') > +size = '4M' > +nbd_sock = os.path.join(iotests.sock_dir, 'nbd_sock') > +nbd_uri = 'nbd+unix:///{}?socket=' + nbd_sock > +nbd: ModuleType nbd is never used and ModuleType is in the types stdlib package, which is not included here. This looks like it can be removed. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 3/3] iotests: Add new nbd-robustness test 2026-11-09 15:36 ` Stefan Hajnoczi @ 2026-11-09 16:06 ` Eric Blake 0 siblings, 0 replies; 12+ messages in thread From: Eric Blake @ 2026-11-09 16:06 UTC (permalink / raw) To: Stefan Hajnoczi Cc: qemu-devel, qemu-stable, berrange, qemu-block, Vladimir Sementsov-Ogievskiy, Kevin Wolf, Hanna Reitz On Mon, Nov 09, 2026 at 08:36:22AM -0700, Stefan Hajnoczi wrote: > On Sat, Nov 07, 2026 at 04:54:38PM -0600, Eric Blake wrote: > > Convert the proof of concept test by Sunday Jiang into an iotest. I > > tried to get libnbd to trigger the situation, but forcing a block > > status command when no status has been initiated is not something that > > libnbd is willing to do. So this results in a hard-coded sequence of > > bytes sent over a raw socket. 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/4091 > > Signed-off-by: Eric Blake <eblake@redhat.com> > > --- > > tests/qemu-iotests/tests/nbd-robustness | 137 ++++++++++++++++++++ > > tests/qemu-iotests/tests/nbd-robustness.out | 5 + > > 2 files changed, 142 insertions(+) > > create mode 100755 tests/qemu-iotests/tests/nbd-robustness > > create mode 100644 tests/qemu-iotests/tests/nbd-robustness.out > > > > diff --git a/tests/qemu-iotests/tests/nbd-robustness b/tests/qemu-iotests/tests/nbd-robustness > > new file mode 100755 > > index 00000000000..602b7060854 > > --- /dev/null > > +++ b/tests/qemu-iotests/tests/nbd-robustness > > @@ -0,0 +1,137 @@ > > +#!/usr/bin/env python3 > > +# group: rw auto quick > > +# > > +# Test cases for NBD robustness against malicious clients > > +# > > +# Copyright (C) 2026 Red Hat, Inc. > > +# > > +# SPDX-License-Identifier: GPL-2.0-or-later > > + > > +import os > > +from contextlib import contextmanager > > + > > +import iotests > > +from iotests import qemu_img_create, qemu_io > > + > > +import socket > > +import struct > > + > > + > > +disk = os.path.join(iotests.test_dir, 'disk') > > +size = '4M' > > +nbd_sock = os.path.join(iotests.sock_dir, 'nbd_sock') > > +nbd_uri = 'nbd+unix:///{}?socket=' + nbd_sock > > +nbd: ModuleType > > nbd is never used and ModuleType is in the types stdlib package, which > is not included here. This looks like it can be removed. Indeed, it was leftover copy-paste from nbd-commands when I was first trying to use libnbd to drive the reproducer, before figuring out that libnbd can't trigger it. Will fix. -- Eric Blake, Principal Software Engineer Red Hat, Inc. Virtualization: qemu.org | libguestfs.org ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-11-10 8:49 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-11-07 22:54 [PATCH for-11.2 v2 0/3] Avoid low-severity NBD denial-of-service attack Eric Blake 2026-11-07 22:54 ` [PATCH v2 1/3] docs: Mention security considerations for NBD Eric Blake 2026-11-09 15:58 ` Stefan Hajnoczi 2026-11-09 20:48 ` Eric Blake 2026-11-10 8:48 ` Daniel P. Berrangé 2026-11-07 22:54 ` [PATCH v2 2/3] nbd/server: Reject rather than assert on non-compliant BLOCK_STATUS Eric Blake 2026-11-09 13:57 ` Eric Blake 2026-11-09 15:45 ` Stefan Hajnoczi 2026-11-09 15:51 ` Stefan Hajnoczi 2026-11-07 22:54 ` [PATCH v2 3/3] iotests: Add new nbd-robustness test Eric Blake 2026-11-09 15:36 ` Stefan Hajnoczi 2026-11-09 16:06 ` Eric Blake
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.