← Our Research

ASI-2026-0012

tOS TLS Stack — Stack Overflow via Improper Record Length Validation

HIGH FIXED CVSS: 8.1 Published: 2026-07-20

Summary

In recv_record of tls.c, the 16-bit record-length field of an incoming TLS record is validated only against the generic TLS_RX_BUF constant (8192 bytes) rather than the actual capacity of the caller-supplied destination buffer. Two call sites in tls_connect(), used to receive the server's ChangeCipherSpec and Finished handshake messages, pass stack buffers of only 8 and 512 bytes respectively. A malicious or compromised TLS server can declare a record length up to 8192 bytes and have that many attacker-controlled bytes written past the end of either stack buffer, corrupting the stack of tls_connect()'s frame. This is reachable by initiating any outbound HTTPS connection (e.g. via wget) to a server under the attacker's control.

How We Found It

After finding the 'clamp exists against a generic constant instead of the real destination buffer' pattern in the NTFS driver in ASI-2026-0006, we looked for it in the network stack this time. While reviewing the TLS handshake code in tls.c, we found that recv_record validated the incoming record length only against the generic TLS_RX_BUF constant (8192 bytes), never against the actual capacity of the destination buffer the caller supplied.

Technical Detail

The 16-bit record-length field of an incoming TLS record was validated only against the generic TLS_RX_BUF constant (8192 bytes), not against the actual capacity of the caller-supplied destination buffer. Two call sites in tls_connect(), used to receive the server's ChangeCipherSpec and Finished handshake messages, pass stack buffers of only 8 and 512 bytes respectively. Since these buffers are far smaller than TLS_RX_BUF, the validation performed by recv_record provided no meaningful protection for these two call sites.

Attack Scenario

A malicious or compromised TLS server can declare a record length up to 8192 bytes and have that many attacker-controlled bytes written past the end of either the 8-byte or 512-byte stack buffer, corrupting the stack of tls_connect()'s frame. This is reachable by initiating any outbound HTTPS connection (e.g. via wget) to a server under the attacker's control.

Root Cause

recv_record() bounded the server-controlled record length against the generic TLS_RX_BUF constant instead of the real capacity of the specific destination buffer passed by each call site, several of which are far smaller than TLS_RX_BUF.

Fix

recv_record() now takes an explicit buffer-capacity parameter and validates the record length against it; every call site passes sizeof() of its actual destination buffer.

Affected Platforms

Artfical tOS < 0.9.116

Weakness Type

CWE-121, CWE-20

Discovered By

Artfical DT Developer Talha Berk Arslan

References