Skip to content

TALOS 2026 2423

talosintelligence.com • October 30, 2026

A out-of-bounds read vulnerability exists in the vtkChacoReader InputGraph2 functionality of vtk (version(s): 9.6.1). A specially crafted chaco can lead to an out-of-bounds read. An attacker can provide a malicious file to trigger this vulnerability.

Confirmed Vulnerable Versions

The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.

vtk (version(s): 9.6.1)

vtk -

8.2 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:H

CWE-125 - Out-of-bounds Read

VTK, or the Visualization Toolkit, is an open-source software system for 3D computer graphics, image processing, and scientific visualization. It provides a large collection of algorithms and data structures for rendering, volume visualization, geometric processing, and interaction.

vtkChacoReader parses the Chaco plain-text graph format — a .graph file encoding topology (vertex count, edge count, 1-based adjacency lists) and an optional .coords file with vertex coordinates. The format represents a graph as a list of vertices, each followed by the IDs of its neighbors. Vertex count and edge count are declared on the first line; subsequent lines list, for each vertex, the 1-based IDs of all adjacent vertices.

The reader parses a malformed Chaco sample without error. When cell data is accessed, ASan reports:

Output grid: 2 points, 1 cell — no warning emitted. The call chain runs from GetCell() (frame #12) through GetPoints() (frame #10) into GetTuple() (frame #0), where the 8-byte heap read lands at address 0x50400003d020 .

The crash occurs in a templated worker function dispatched by GetPoints() . The relevant line:

GetTuple() at LINE_88 reads a point’s coordinates from the points array using idsPtr[i] as an index. idsPtr is a raw pointer into a list of point IDs passed down from GetCell() .

One level up in the call stack (frame #12), vtkUnstructuredGrid::GetCell() retrieves those point IDs:

this->Connectivity is a vtkCellArray — an array that stores, for each cell, the list of point IDs that define it. GetCellAtId() at LINE_375 reads point IDs from that array into cell->PointIds . Those IDs are then passed to GetPoints() at LINE_376 , which dispatches to the worker shown above.

Connectivity is populated by SetCells() at LINE_616 in vtkChacoReader::ReadFile() , which builds the grid. The adjacency data fed into that connectivity comes from InputGraph2() , called at LINE_468 :

InputGraph2() reads each neighbor vertex ID — attacker-controlled — from the .graph file via ReadInt() and stores it in the adjacency output array:

The guard at LINE_1200 caps total adjacency count, not individual values. The valid range for neighbor is [1, nvtxs] — each neighbor ID should reference an existing vertex. But whether neighbor falls within that range is never verified; the value is stored as-is at LINE_1209 . This is the design flaw: a bounds check on neighbor between LINE_1175 and LINE_1209 would prevent any out-of-range vertex ID from reaching the output.

Back in ReadFile() , points are allocated at LINE_354 for exactly NumberOfVertices entries (attacker-controlled, read from the first line of the .graph file). The adjacency array returned by InputGraph2() is then converted into cell connectivity — each adjacency entry becomes a two-point VTK_LINE cell:

The condition nbor > id at LINE_557 filters duplicate edges — it ensures each edge is stored once. It is not a bounds check. At LINE_616 , SetCells() commits the full connectivity array to the output grid.

A neighbor ID read from the file at LINE_1175 flows through InputGraph2() (stored at LINE_1209 ), into the adjacency array nbors , through ReadFile() (converted to 0-based at LINE_553 , stored as a point ID at LINE_570 ), and into cell connectivity via SetCells() at LINE_616 . When GetCell() later resolves that cell, GetTuple() uses the stored ID as an index into the points array. Since points are allocated for NumberOfVertices entries, any index above NumberOfVertices - 1 reads beyond the buffer.

File content controls the read offset ( neighbor field) and the buffer size ( num_vertices header) independently. A specially crafted .graph file causes denial of service on cell access; on non-instrumented builds, heap contents leak as double coordinate values — e.g. through exported geometry.

An out-of-bounds read vulnerability exists in VTK’s vtkChacoReader class. A specially crafted .graph file containing an out-of-range neighbor vertex ID triggers a heap-buffer-overflow read when the application accesses cell data on the resulting vtkUnstructuredGrid .

Vendor Response (CVE-2026-9535)

Vendor Link:

2026-06-23 - Vendor Notification 2026-06-25 - Vendor Acknowledged 2026-06-30 - 7-Day 2026-07-02 - Follow-Up Sent 2026-07-07 - Vendor Replied, Dev Team Working 2026-08-07 - 45-Day 2026-08-22 - 60-Day 2026-09-15 - Follow-Up Sent 2026-09-21 - 90-Day 2026-09-23 - Vendor Replied, Dev Team Working 2026-10-12 - Advised Vendor Cisco Will Publish And Close Out

Emmanuel Tacheau of Cisco Talos

Extracted Entities

Attack Types (1)

CVEs (1)

CWE Weaknesses (1)

Platforms (1)