[Libguestfs] LIBNBD SECURITY: Negative results from nbd_get_size()

Eric Blake eblake at redhat.com
Tue Sep 26 19:12:27 UTC 2023


We have discovered a security flaw with potential minor impact in
libnbd.

Lifecycle
---------

Reported: 2023-09-17  Fixed: 2023-09-22  Published: 2023-09-26

At the time of this email, the Red Hat security team is analyzing
potential security impacts to determine if a CVE is warranted against
libnbd; if one is assigned, a followup email will announce that
identifier.  However, even if a CVE is not assigned to libnbd, the
issues documented here warrant an audit of clients that utilize the
nbd_get_size() API from libnbd, to see if they might be subject to a
weakness when interpreting a large size as a negative value.  The
libnbd developers felt it more important to issue this security notice
prior to the release of v1.18 than to hold up the release schedule
waiting for final analysis on whether libnbd needs a CVE.

Credit
------

Reported by Rich Jones (rjones at redhat.com) during fuzz tests, patched
by Eric Blake <eblake at redhat.com>

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

libnbd is a Network Block Device (NBD) client library.  The NBD
protocol states that a server advertises the size of an export using a
64-bit unsigned number.  In turn, libnbd has an API nbd_get_size()
that returns int64_t, documenting that a non-negative value is a
successful return of the server's export size, and -1 is an error
indicator with a corresponding error message in nbd_get_error(3).
This leads to confusing results when talking to a server that
advertises an export with an unsigned size of 2^63 bytes or larger: a
client that tests 'result < 0' would treat the size as an error
although libnbd did not provide an error message; while a client that
tests 'result == -1' and stores size as a signed integer could end up
seeing a negative value as success, and possibly go on to encounter
subsequent logic issues due to integer overflow or iteration bounds
that are not expecting comparison against a negative value.  This
confusing API result has been present in all stable releases of
libnbd, since v1.0 in April 2019.  In patched libnbd, the API now
uniformly treats all large export sizes as an EOVERFLOW error with a
return value of -1 and corresponding error message.

In the efforts to patch the nbd_get_size() issue in stable libnbd, two
additional related issues were identified that were introduced in the
experimental v1.17.4 release: code added for 64-bit NBD extensions
could hit libnbd assertion failures during the nbd_block_status() API
based on actions taken by a malicious server (one by intentionally
advertising a large export size regardless of whether extended headers
are in use, the other by intentionally disobeying the NBD protocol for
the contents of a 64-bit block status reply when extended headers are
in use).  Odd-numbered minor version releases have always been
considered experimental; production systems should only be using
even-numbered minor version releases, and thus are not vulnerable to a
server-triggered assertion failure.

Test if libnbd is vulnerable
----------------------------

There are no direct methods for testing whether nbd_get_size() will
convert a large export size into an EOVERFLOW error, when using a
compliant server.  However, the libnbd patches include instructions
for making one-off modifications to qemu to create an intentionally
non-compliant server for reproducing all scenarios described in this
notice.  In general, it is probably faster to upgrade to a known-good
libnbd than to try and test if an installed libnbd is still
vulnerable.

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

As a mitigating factor, no known production servers (such as
nbd-server, qemu-nbd, nbdkit) will advertise an export size large
enough to overflow the subset of non-negative int64_t values.  An
application that insists on using TLS to connect only to a known-good
server will never encounter a size that would result in an
undocumented result to nbd_get_size().  Without TLS, an application
that wishes to deal solely with positive sizes for exports should
check that nbd_get_size() is non-negative, rather than the weaker
comparison of the result to just -1.  Other libnbd API take offset
parameters as a uint64_t; an audit of these APIs did not find any
scenarios where a negative size value returned by nbd_get_size() and
then converted to uint64_t could cause any further misbehavior in
libnbd.

Fixes
-----

The original nbd_get_size(3) ambiguous return value flaw was
introduced in libnbd v0.1 (commit 40881fce75), when the API was
introduced.  The server-triggered assertion failures on
nbd_block_status(3) were introduced in libnbd v1.17.4 (commits
e8d837d306 and ab992766cd); there are no plans to release a
development v1.17.6 containing the fixes, since stable v1.18.0 is
scheduled for 27 September 2023.  As of this email, the following
branches have been patched:

* development branch (1.17)

https://gitlab.com/nbdkit/libnbd/-/commit/0f8ee8c6bd6dd93de771e6d4da87ec5a59504aae
https://gitlab.com/nbdkit/libnbd/-/commit/dbc08c932c17e72d42944a5df447d0ea714e896a
https://gitlab.com/nbdkit/libnbd/-/commit/47797419dd56a0d1c156ff266c10620ea5fb56fb
  no intentions to release 1.17.6; instead use libnbd >= 1.18.0 from
  http://download.libguestfs.org/libnbd/1.18-stable/

* stable branch 1.16

https://gitlab.com/nbdkit/libnbd/-/commit/f03330181229360a1a97a264aa956fea54c657de
  or use libnbd >= 1.16.5 from
  http://download.libguestfs.org/libnbd/1.16-stable/

* stable branch 1.14

https://gitlab.com/nbdkit/libnbd/-/commit/258ee95fa2acfa264b05c0346c6c2fdac7eb5322

Contact the developers if a release of 1.14.3 is required but not yet listed at
  http://download.libguestfs.org/libnbd/1.14-stable/

* all earlier stable branches (1.0 through 1.12)

Backports of 0f8ee8c6bd are not deemed high priority at this time;
contact the developers if a new stable release is required

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org


More information about the Libguestfs mailing list