See how libguestfs compares to other vendors in security performance
Affected component: hivex, the Windows Registry hive parsing library. Affected component: the big-data ("db") block list loop in hivexvaluevalue (lib/value.c), used on the default read-only parse path by libguestfs, virt-win-reg, guestfish, and hivexget.
Tested version(s): Release v1.3.24, pinned tag commit 7996d79 (2024-08-31), the latest release tag. The same code is present on the default branch master HEAD unchanged. Reviewed by static source review of the released source at the pinned commit.
Details:
Out-of-bounds read while reading a registry value whose data uses a big-data ("db") block, driven by an attacker-controlled block count that is never bounded against the block that holds the block list.
Class: CWE-125 Out-of-bounds Read, CWE-129 Improper Validation of Array Index.
Root cause (file:line). hivex opens a hive read-only with hivexopen (lib/handle.c:101), maps the file, and records the start offset of every used block in a bitmap. The per-reference validation macro ISVALIDBLOCK (lib/hivex-internal.h:74) confirms only that an offset is 4-aligned, inside the file, and the start of a used block. It does not bound an array read that begins inside a valid block and runs off its end.
When a caller reads a value's data through hivexvaluevalue (lib/value.c:316), and the declared data length is larger than the single data block that holds it, and that block carries the id "db", execution enters the big-data branch (lib/value.c:386). There the code reads a 16-bit block count nrblocks and a block list offset from the db record (lib/value.c:398 and lib/value.c:400, db record layout at lib/hivex-internal.h:249), validates only that the block list start is a valid block (lib/value.c:401), then loops for (i = 0; i < nrblocks; ++i) and reads bl->offset[i] (lib/value.c:411 to lib/value.c:432). There is no check that the block list block is large enough to hold nrblocks four-byte offsets. nrblocks is read straight from the file and can be up to 65535, so the loop can index up to about 262140 bytes from a block list block that can be as small as 8 bytes, reading past the end of that block and past the end of the mapped file. Every sibling list walk in hivex does perform the missing check: the value list in hivexgetvalues (lib/value.c:88, "4 + nrvalues 4 > len"), and the lf, li, and ri lists in getchildren (lib/node.c:408, lib/node.c:442, lib/node.c:469). The db block list walk is the one place that omits the comparison.
Attacker model. An administrator, a forensic workflow, or a libguestfs based pipeline reads values out of a hive that arrived from an untrusted source, such as a guest disk image, an uploaded registry export, or a sample under analysis. Tools such as virt-win-reg, guestfish hivex commands, and hivexget call this path while enumerating values. The structural gates are a parseable hive header (a valid regf header with a recomputed checksum, which is an xor of the header dwords) and a value whose data points to a db block, all file-controlled. No password, write mode, option, or non-default build flag is required.
Impact. Out-of-bounds read of up to about 262140 bytes past the block list block, crossing the end of the mapping when the block list is placed near the end of the file, leading to a likely crash (denial of service) in any process that reads values from an untrusted hive. The out-of-bounds offset value is passed to ISVALIDBLOCK rather than returned to the caller, so a direct read-back of leaked bytes is not demonstrated. No out-of-bounds write and no code execution were shown.
Fix. In the big-data branch of hivexvaluevalue, after reading nrblocks and the block list, add "sizet bllen = blocklen (h, blocklistoffset, NULL); if (4 + nrblocks 4 > bllen) { free (ret); return error; }" before the loop, matching the value list guard at lib/value.c:88. Defense in depth, cap nrblocks with an explicit limit like the existing HIVEXMAXVALUES and HIVEXMAXSUBKEYS constants.
Verification (static only). The full chain was confirmed against the released source at the pinned commit 7996d79. No hive was built, no tool was run, and no live system was contacted. The crash and faulting address were not confirmed at runtime.
Distinct from prior hivex advisories: CVE-2014-9273 (lib/handle.c on tiny files), CVE-2021-3504 (missing bounds check in hivexopen, lib/handle.c), and CVE-2021-3622 (recursion stack overflow in getchildren, lib/node.c). None covers the db big-data block list loop in hivexvaluevalue.
A flaw was found in libnbd. A client did not always correctly verify the NBD server's certificate when using TLS to connect to an NBD server. This would allow a man-in-the-middle attack on NBD traffic. After investigation, several separate related problems were found.
Reference: https://lists.libguestfs.org/archives/list/guestfs@lists.libguestfs.org/message/LHR3BW6RJ7K4BJBQIYV3GTZLSY27VZO2
A flaw was found in libnbd. A client did not always correctly verify the NBD server's certificate when using TLS to connect to an NBD server. This would allow a man-in-the-middle attack on NBD traffic. After investigation, several separate related problems were found.
Reference: https://lists.libguestfs.org/archives/list/guestfs@lists.libguestfs.org/message/LHR3BW6RJ7K4BJBQIYV3GTZLSY27VZO2
A buffer overflow was found in getkeys getkeys()
When calculating the greatest possible number of matching keys in getkeys(), the current expression
MIN (1, ks->nrkeys)
is wrong -- it will return at most 1.
If all "nrkeys" keys match however, then we require "nrkeys" non-NULL entries in the result array; in other words, we need
MAX (1, ks->nrkeys)
(The comment just above the expression is correct; the code is wrong.)
This buffer overflow is easiest to trigger in those guestfs tools that parse the "--key" option in C; that is, with "OPTIONkey". For example, the command
$ virt-cat $(seq -f '--key /dev/sda2:key:%g' 200) -d DOMAIN /no-such-file
which passes 200 (different) passphrases for the LUKS-encrypted block device "/dev/sda2", crashes with a SIGSEGV.
Double free vulnerability in inspect-fs.c in LibguestFS 1.20.x before 1.20.7, 1.21.x, 1.22.0, and 1.23.0 allows remote attackers to cause a denial of service (crash) via empty guest files.
libguestfs is a library for accessing and modifying guest disk images. It was found that guestfish, which enables shell scripting and command line access to libguestfs, insecurely created the temporary directory used to store the network socket when started in server mode (using the "--listen" option). If guestfish were run with the "--listen" option, a local attacker could use this flaw to intercept and modify other users' guestfish commands, allowing them to perform arbitrary guestfish actions (such as modifying virtual machines) with the privileges of a different user, or use this flaw to obtain authentication credentials.
Acknowledgements:
This issue was discovered by Michael Scherer of the Red Hat Regional IT team.
virt-edit in libguestfs before 1.18.0 does not preserve the permissions from the original file and saves the new file with world-readable permissions when editing, which might allow local guest users to obtain sensitive information.
libguestfs before 1.5.23, as used in virt-v2v, virt-inspector 1.5.3 and earlier, and possibly other products, when a raw-format disk image is used, allows local guest OS administrators to read files from the host via a crafted (1) qcow2, (2) VMDK, or (3) VDI header, related to lack of support for a disk format specifier.