[NBDKIT SECURITY] two flaws with large block status requests
by Eric Blake
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 <stenavin(a)gmail.com>;
the second issue was reported by Eric Blake while investigating the
first. Both issues were patched by Eric Blake <eblake(a)redhat.com>.
Reviewed by Rich Jones <rjones(a)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/26455d452574f60119a79aea5a9f437...
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/2680be00af8edd997e1c9b3765180ed...
Both patches were initially posted on April 23, 2025:
https://lists.libguestfs.org/archives/list/guestfs@lists.libguestfs.org/t...
* development branch (1.43)
https://gitlab.com/nbdkit/nbdkit/-/commit/e6f96bd1b77c0cc927ce6aeff650b52...
https://gitlab.com/nbdkit/nbdkit/-/commit/a486f88d1eea653ea88b0bf8804c482...
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/c3c1950867ea8d9c2108ff066ed9e78...
https://gitlab.com/nbdkit/nbdkit/-/commit/c3ed72811aca5684490b198737b2f0b...
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/2959966cfa9e8675efea286eba12d09...
https://gitlab.com/nbdkit/nbdkit/-/commit/07986b5ce477dd504bd8cd11c7d455b...
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/e614d87fdf236ccf6a9c66ac0562064...
https://gitlab.com/nbdkit/nbdkit/-/commit/cf2dcbf3d06097d29693bd3943e9efc...
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
1 week, 6 days