REDHAT-BUG-2565405: Low severity vulnerability
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.