We have discovered two distinct but related potential Denial of
Service Attacks in nbdkit, when a client requests large block status.

Lifecycle
---------

For the first issue (general server flaw):

Reported: 2025-04-22  Fixed: 2025-05-08  Published: 2025-04-23

This has been assigned CVE-2025-47711.

For the second issue (blocksize filter flaw):

Reported: 2025-04-22  Fixed: 2025-05-08  Published: 2025-04-23

This has been assigned CVE-2025-47712.


Credit
------

The first issue was reported by Nikolay Ivanets <stena...@gmail.com>;
the second issue was reported by Eric Blake while investigating the
first.  Both issues were patched by Eric Blake <ebl...@redhat.com>.

Reviewed by Rich Jones <rjo...@redhat.com>.

Description
-----------

nbdkit is a Network Block Device (NBD) server with multiple plugins,
and includes the ability for plugins to report block status (also
known as extents) when a client requests NBD_CMD_BLOCK_STATUS.  Nbdkit
does not yet support the NBD protocol extensions for 64-bit block
status, so it must convert 64-bit plugin information into 32-bit wire
responses.

However, two separate flaws in the handling of large block status
requests (near the 32-bit protocol limit of 4GiB) can result in the
server crashing with an assertion failure on a well-formed request
from the client.  A malicious client could abuse these assertion
failures as a denial of service attack to prevent the server from
responding to other clients.  Neither flaw can be exploited for any
effects beyond premature death of the server.

The first flaw was in the generic server code.  If a client requests
exactly 2**32-1 bytes of block status, while a plugin implements an
.extents callback that reports a single extent with larger size, then
the server would crash rather than properly truncating the plugin's
response to the 32-bit protocol limit.  No other request size triggers
the flaw, and the flaw is also avoided for any plugin or filter that
never reports a value larger than 32 bits in its .extents callback.

The second flaw was in the blocksize filter.  If a client requests a
large block status length that is not aligned to the sector size
enforced by the filter, and rounding the request up to the next
aligned boundary overflowed a 32-bit number, then the filter would
crash the server rather than properly truncating the request to a
lower aligned boundary.

Mitigating both issues is the fact that most clients do not send
unaligned block status requests, and the attacks are not possible if
nbdkit is used with TLS to reject untrusted clients.  The second issue
is also mitigated by the fact that many nbdkit command lines do not
need to use the blocksize filter.

Similarly, it is possible to prevent the attacks by arranging clients
and servers to use a trusted network (for example, using nbdkit -U for
a local Unix socket, rather than exposing the connection over TCP).

The generic server flaw affects a wider range of nbdkit releases
(since v1.11.10) than the blocksize filter flaw (since v1.21.16).
Fixed versions of nbdkit ensure that all valid client sizes to
NBD_CMD_BLOCK_STATUS are handled gracefully without assertion
failures.

Test if nbdkit is a vulnerable version
--------------------------------------

The following command lines demonstrate whether your version of nbdkit
is vulnerable to either issue:

Generic server flaw:
$ nbdkit eval get_size='echo 5G' extents='echo 0 4G 1; echo 4G 1G 2' \
  --run 'nbdsh --base-allocation -u "$uri" \
         -c "h.block_status(2**32-1, 0, lambda a,b,c,d: 0)"'

Blocksize filter flaw:
$ nbdkit eval get_size='echo 5G' extents='echo 0 4G 1; echo 4G 1G 2' \
  --filter=blocksize minblock=512 \
  --run 'nbdsh --base-allocation -u "$uri" \
         -c "h.block_status(2**32-1, 0, lambda a,b,c,d: 0)"'

If either command reports an nbdkit assertion failure before nbdsh
mentions that the transport endpoint is not connected, then nbdkit is
flawed.  A working nbdkit has no output and a 0 exit status.

Workarounds
-----------

In general, it is recommended to use TLS to avoid untrusted clients.
If TLS is not used, it is possible to use the blocksize-policy filter
(add '--filter=blocksize-policy blocksize-minimum=512' or similar to
the command line) to reject unaligned client requests prior to
reaching either assertion failure.  However, use of the
blocksize-policy filter earlier in the command line than the blocksize
filter is atypical (the blocksize filter is designed to let clients
use unaligned requests, while the blocksize-policy filter is designed
to require clients to use aligned requests, so combining them changes
the semantics of what the server will allow from the client), and
placing the blocksize-policy filter after the blocksize filter does
not mitigate the second flaw.

Fixes
-----

The first flaw affects all stable nbdkit versions 1.12 through 1.42.2;
the second flaw affects all stable nbdkit versions 1.22 through
1.42.2.  Both also affect development versions through 1.43.6.  A fix
is available for the current development branch, as well as several of
the newer stable branches, as detailed below.

The first flaw was introduced at the time the .extents callback was
added in March 2019, in development release v1.11.10:
  
https://gitlab.com/nbdkit/nbdkit/-/commit/26455d452574f60119a79aea5a9f437c1d222ae5

The second flaw was introduced while fixing another .extents bug in
the blocksize filter in July 2020, in development release v1.21.16:
  
https://gitlab.com/nbdkit/nbdkit/-/commit/2680be00af8edd997e1c9b3765180ed036da1e91

Both patches were initially posted on April 23, 2025:
  
https://lists.libguestfs.org/archives/list/guestfs@lists.libguestfs.org/thread/RYWP56S5Z7XUDFUFHB72AGZ6EAUTC73B/

* development branch (1.43)
  
https://gitlab.com/nbdkit/nbdkit/-/commit/e6f96bd1b77c0cc927ce6aeff650b52238304f39
  
https://gitlab.com/nbdkit/nbdkit/-/commit/a486f88d1eea653ea88b0bf8804c4825dab25ec7
  or use nbdkit >= 1.43.7 from
  http://download.libguestfs.org/nbdkit/1.43-development/

* stable branch 1.42
  
https://gitlab.com/nbdkit/nbdkit/-/commit/c3c1950867ea8d9c2108ff066ed9e78dde3cfc3f
  
https://gitlab.com/nbdkit/nbdkit/-/commit/c3ed72811aca5684490b198737b2f0b921741547
  or use nbdkit >= 1.42.3 from
  http://download.libguestfs.org/nbdkit/1.42-stable/

* stable branch 1.40
  
https://gitlab.com/nbdkit/nbdkit/-/commit/2959966cfa9e8675efea286eba12d096873f69cd
  
https://gitlab.com/nbdkit/nbdkit/-/commit/07986b5ce477dd504bd8cd11c7d455bdaeb86c36
  or use nbdkit >= 1.40.6 from
  http://download.libguestfs.org/nbdkit/1.40-stable/

* stable branch 1.38
  
https://gitlab.com/nbdkit/nbdkit/-/commit/e614d87fdf236ccf6a9c66ac05620646137c0668
  
https://gitlab.com/nbdkit/nbdkit/-/commit/cf2dcbf3d06097d29693bd3943e9efcb460e7a42
  or use nbdkit >= 1.38.6 from
  http://download.libguestfs.org/nbdkit/1.38-stable/

Feel free to request help if you have a reason to backport either
patch to an older branch.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org
_______________________________________________
Libguestfs mailing list -- guestfs@lists.libguestfs.org
To unsubscribe send an email to guestfs-le...@lists.libguestfs.org

Reply via email to