CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-C55G-RP4X-FX84
7.8

GHSA-C55G-RP4X-FX84: Integer Overflow and Out-of-Bounds Access in DirectX Tool Kit SpriteFont Parser

Alon Barad
Alon Barad
Software Engineer

May 18, 2026·9 min read·2 visits

No Known Exploit

Executive Summary (TL;DR)

A 32-bit integer overflow in the DirectX Tool Kit's `BinaryReader::ReadArray` function allows crafted `.spritefont` files to bypass size validation. This leads to heap buffer overflows or out-of-bounds reads when parsing maliciously structured font files on 32-bit architectures.

The Microsoft DirectX Tool Kit (DirectXTK and DirectXTK12) contains an integer overflow vulnerability in its SpriteFont parsing implementation, specifically affecting 32-bit application builds. The flaw resides in the `DirectX::BinaryReader::ReadArray` template function, where a multiplication operation using 32-bit arithmetic wraps around when processing maliciously crafted `.spritefont` files. This miscalculation circumvents pointer arithmetic safety checks, leading to out-of-bounds memory access. Successful exploitation allows an attacker to achieve memory corruption or information disclosure within the application parsing the untrusted file.

Vulnerability Overview

The Microsoft DirectX Tool Kit (DirectXTK) is a comprehensive collection of helper classes for writing Direct3D 11 and Direct3D 12 C++ code. Within this library, the SpriteFont component is responsible for loading and rendering bitmap fonts stored in the proprietary .spritefont binary format. These font files contain structured metadata mapping character glyphs to specific texture coordinates, alongside spacing and kerning metrics. Applications utilizing the library rely on the BinaryReader component to sequentially parse these binary structures from disk or memory into active C++ objects.

An integer overflow vulnerability (CWE-190) exists in the memory parsing logic of the BinaryReader::ReadArray template function. This flaw exclusively affects applications compiled for 32-bit architectures, including x86 and 32-bit ARM environments. The vulnerability manifests during the byte size calculation for incoming asset arrays. An attacker can construct a malicious font file that triggers a mathematical wraparound during this calculation, fundamentally breaking the bounds validation mechanism.

The attack surface exposed by this vulnerability depends heavily on the application's asset management architecture. Game engines and graphical applications frequently load .spritefont files dynamically from user-modifiable directories, downloaded mod packages, or over network streams. If an application parses an untrusted .spritefont file, the vulnerability triggers without requiring any active user interaction beyond the initiation of the asset loading sequence.

The primary consequence of this integer overflow is a subsequent out-of-bounds (OOB) memory access condition. Because the internal size calculation yields an erroneously small value, the system allocates insufficient spatial bounds for the underlying parsing operations. Subsequent extraction of glyph or kerning data from the binary stream will overrun the intended memory boundaries, allowing the attacker to corrupt adjacent heap structures or disclose sensitive memory contents.

Root Cause Analysis

The core vulnerability stems from the implementation of the ReadArray template within the Src/BinaryReader.h header. This function determines the memory span required to process an array of elements by multiplying the size of the target structure sizeof(T) by the declared elementCount parsed directly from the .spritefont file. In C++, the type of the result of a multiplication operation is determined by the types of its operands. On 32-bit architectures, the size_t type used to represent sizeof(T) and memory offsets is strictly 32 bits wide.

When the ReadArray function computes sizeof(T) * elementCount, the operation utilizes a 32-bit arithmetic unit. If a maliciously crafted .spritefont file supplies an elementCount sufficiently large, the true product exceeds the maximum value representable by a 32-bit unsigned integer (0xFFFFFFFF). The multiplication silently overflows, truncating the higher-order bits and leaving a small, wrapped-around integer value. This incorrectly small byte count is then used to advance the read pointer.

The implementation attempts to prevent buffer overruns using the safety check if (newPos < mPos). This validation assumes that an excessive pointer increment will wrap around the process's 32-bit virtual address space, resulting in a destination pointer mathematically lower than the source pointer. However, the preceding multiplication overflow produces an increment value that is artificially small. The pointer arithmetic mPos + (wrapped_small_value) easily fits within the valid address space.

Consider a scenario where sizeof(T) is 16 bytes, and the attacker configures the font file to declare an elementCount of 0x20000001. The true mathematical product is 0x200000010. The 32-bit truncation discards the upper bits, yielding a final increment of just 0x10 (16 bytes). The safety check newPos < mPos evaluates to false because mPos + 0x10 does not wrap the address space. The application then assumes mPos points to a valid sequence of 0x20000001 elements, processing the remaining binary data well beyond the actual bounds of the allocated buffer.

Code Analysis

Analyzing the vulnerable implementation in Src/BinaryReader.h reveals the direct mechanism of the failure. The original code utilizes native size_t precision for the entire calculation. The dependency on compiler-defined integer widths creates a distinct divergence in security posture between 32-bit and 64-bit build targets.

// Vulnerable Code Block
uint8_t const* newPos = mPos + sizeof(T) * elementCount;
 
if (newPos < mPos)
    throw std::overflow_error("ReadArray");

In this block, the pointer increment and the validation occur sequentially. The flaw exists specifically in the sizeof(T) * elementCount expression. The compiler enforces 32-bit multiplication before the result is added to the pointer. The subsequent std::overflow_error check completely fails to identify the error because the wraparound occurred during the multiplication phase, not the pointer addition phase.

The patched implementation introduces explicit type casting to enforce 64-bit precision during the arithmetic phase, regardless of the target architecture. By promoting both operands to uint64_t, the intermediate product can safely contain the maximum possible size requested by a 32-bit integer, preventing the arithmetic wraparound.

// Patched Code Block
uint64_t byteCount = uint64_t(sizeof(T)) * uint64_t(elementCount);
if (byteCount > UINT32_MAX)
    throw std::overflow_error("ReadArray");
 
uint8_t const* newPos = mPos + static_cast<size_t>(byteCount);
 
if (newPos < mPos)
    throw std::overflow_error("ReadArray");

This fix is complete and robust. It guarantees that the arithmetic cannot overflow within the uint64_t bounds. The explicit threshold check against UINT32_MAX ensures that the subsequent cast back to size_t will not truncate the value on 32-bit systems. The original pointer-wrap check is maintained as a defense-in-depth measure.

Exploitation Methodology

Exploitation of this vulnerability requires the attacker to deliver a carefully structured .spritefont binary to the target application. This typically involves modifying game assets, leveraging user-generated content (UGC) features, or intercepting insecure network transmissions. The attacker must possess an understanding of the specific internal data structures processed by the ReadArray function to manipulate the elementCount parameter effectively.

The payload construction begins by identifying a target structure type T within the SpriteFont parsing sequence, such as a glyph definition or kerning pair record. The attacker calculates a specific elementCount that, when multiplied by sizeof(T), modulo 2^32, results in a minor integer value matching the size of the actual trailing payload. This precise alignment tricks the parser into validating the short header while preparing to iterate over an immense number of nonexistent elements.

Once the application accepts the malformed size, the execution flow enters a parsing loop designed to extract data for each of the declared elements. The loop iterates based on the massive elementCount variable, continuously reading from or writing to the memory segment originating at mPos. Since the backing buffer or mapped file view is substantially smaller than the iteration count implies, the loop systematically processes memory outside the intended boundaries.

The outcome of this exploitation phase depends heavily on the memory layout adjacent to the source buffer. If the BinaryReader operates over a dynamically allocated heap buffer, the parser will read from adjacent heap allocations, potentially crashing the application via an unmapped memory access violation. In specific scenarios where the extracted data influences application state or triggers subsequent memory operations, the vulnerability provides a primitive for arbitrary memory corruption.

Impact Assessment

The security impact of GHSA-C55G-RP4X-FX84 is classified as High due to the potential for significant memory corruption within the application's execution space. While the primary primitive is an out-of-bounds read, the structure of the DirectX::BinaryReader implies the vulnerability frequently manifests as a heap buffer overflow. The exact impact gradient scales linearly with the complexity of the application utilizing the DirectXTK library.

From a confidentiality perspective, the out-of-bounds access allows the application to ingest adjacent memory regions as if they were valid font metrics. If the application subsequently renders this data, logs it, or transmits it, an attacker recovers sensitive information resident in the heap. This data exposure compromises the integrity of the application's memory isolation boundaries.

The integrity and availability impacts are direct and severe for the running process. Continuous sequential reading beyond the limits of a mapped file or heap allocation inevitably leads to a memory access violation, resulting in an immediate application crash. If the parsed values are utilized in subsequent allocation sizes or memory copies, an attacker gains substantial leverage to overwrite critical application state.

The impact scope is strictly constrained by the compilation target. Applications built for 64-bit architectures (x64, ARM64) remain completely unexploitable. On these platforms, size_t provides 64 bits of width, granting the arithmetic operation sufficient capacity to calculate the correct byte count. The pointer arithmetic check functions exactly as intended, neutralizing the attack path.

Remediation and Mitigation

The authoritative remediation for this vulnerability requires upgrading the dependent DirectXTK or DirectXTK12 libraries to the May 2026 release or any subsequent version. The core maintainers have integrated explicit 64-bit integer promotion and boundary validation into the parsing logic. Implementing this update addresses the root cause of the arithmetic flaw at the source level.

Software development teams must recompile their applications after updating the library dependencies. Because BinaryReader::ReadArray is implemented as a C++ template function within a header file (Src/BinaryReader.h), the vulnerable logic is instantiated directly into the compiled binaries of the consuming application. Merely updating pre-compiled dynamic-link libraries (DLLs), if applicable, is insufficient. A full rebuild of the project is mandatory to propagate the patched template code.

As an architectural mitigation, organizations should accelerate the deprecation of 32-bit builds for graphical applications. Migrating the compilation target exclusively to 64-bit architectures (x64 or ARM64) neutralizes this specific vulnerability class. In 64-bit environments, the native width of size_t inherently prevents the elementCount multiplication from overflowing during standard file processing workloads.

To implement defense-in-depth, applications processing user-supplied assets should validate file sizes and structural bounds before initiating complex parsing routines. Enforcing maximum allowable file sizes for .spritefont assets effectively truncates payloads attempting to declare structurally impossible element counts. Additionally, integrating robust exploit mitigation technologies such as Address Space Layout Randomization (ASLR) and Data Execution Prevention (DEP) complicates the weaponization of the underlying out-of-bounds access.

Official Patches

MicrosoftDirectXTK May 2026 Official Release

Fix Analysis (1)

Technical Appendix

CVSS Score
7.8/ 10
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

Affected Systems

Microsoft DirectXTK (32-bit builds)Microsoft DirectXTK12 (32-bit builds)Applications parsing .spritefont files using affected library versions

Affected Versions Detail

Product
Affected Versions
Fixed Version
DirectXTK
Microsoft
< May 2026May 2026
DirectXTK12
Microsoft
< May 2026May 2026
AttributeDetail
CWE IDCWE-190
Attack VectorLocal/Remote via Crafted File
CVSS Score7.8
Vulnerability ImpactOut-of-Bounds Memory Access
Architecture Dependency32-bit only (x86, ARM32)
Exploit StatusNone documented

MITRE ATT&CK Mapping

T1203Exploitation for Client Execution
Execution
T1059Command and Scripting Interpreter
Execution
CWE-190
Integer Overflow or Wraparound

The software performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value.

Vulnerability Timeline

Fix committed to DirectXTK and DirectXTK12 repositories.
2026-04-20
Official May 2026 release of DirectXTK libraries.
2026-05-01

References & Sources

  • [1]GitHub Advisory: GHSA-C55G-RP4X-FX84
  • [2]DirectXTK Fix Commit
  • [3]DirectXTK12 Fix Commit

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.