oss-sec mailing list archives
ngtcp2: qlog_parameters_set_transport_params_stack_overflow [CVE-2026-40170]
From: Alan Coopersmith <alan.coopersmith () oracle com>
Date: Fri, 17 Apr 2026 09:53:26 -0700
https://github.com/ngtcp2/ngtcp2/security/advisories/GHSA-f523-465f-8c8f advises:
qlog_parameters_set_transport_params_stack_overflow
tatsuhiro-t published GHSA-f523-465f-8c8f Apr 16, 2026
Package: ngtcp2
Affected versions: <= 1.22.0
Patched versions: 1.22.1
Summary
-------
ngtcp2_qlog_parameters_set_transport_params() serializes transport parameters
into a fixed stack buffer (uint8_t buf[1024]) without complete bounds checks.
When qlog is enabled and peer-controlled transport parameters are large enough,
this causes a stack buffer overflow (ASAN confirmed).
Details
-------
1. The trigger starts in normal handshake processing.
ngtcp2_conn_set_remote_transport_params sends peer transport parameters to
qlog serialization at lib/ngtcp2_conn.c#L11670:
ngtcp2_qlog_parameters_set_transport_params(&conn->qlog, params, conn->server,
NGTCP2_QLOG_SIDE_REMOTE);
2. Inside ngtcp2_qlog_parameters_set_transport_params, JSON is built in a fixed
stack buffer (buf[1024]) and a moving pointer p (lib/ngtcp2_qlog.c#L902,
lib/ngtcp2_qlog.c#L905):
void ngtcp2_qlog_parameters_set_transport_params(...) {
uint8_t buf[1024];
uint8_t *p = buf;
...
}
3. The function then appends many peer-influenced fields
(CID/token/preferred-address data/limits).
Representative writes are visible at lib/ngtcp2_qlog.c#L1004 and
lib/ngtcp2_qlog.c#L1006:
p = write_pair_cid(p, "initial_source_connection_id", ¶ms->initial_scid);
...
p = write_pair_hex(p, "data", paddr->stateless_reset_token,
sizeof(paddr->stateless_reset_token));
4. There is no end-to-end guard that guarantees the full serialized output fits
into buf.
With sufficiently large combined field output, p advances beyond buf + 1024,
and later helper writes become stack out-of-bounds writes.
5. The final write that actually crosses the boundary happens in the
hex-encoding path used by qlog helpers.
In write_hex (lib/ngtcp2_qlog.c#L58), the pointer is passed through to
ngtcp2_encode_hex:
static uint8_t *write_hex(uint8_t *p, const uint8_t *data, size_t datalen) {
*p++ = '"';
p = ngtcp2_encode_hex(p, data, datalen);
*p++ = '"';
return p;
}
Then ngtcp2_encode_hex (lib/ngtcp2_str.c#L51) writes bytes sequentially to
dest:
uint8_t *ngtcp2_encode_hex(uint8_t *dest, const uint8_t *data, size_t len) {
for (; len--;) {
*dest++ = low[(size_t)(*data >> 4)];
*dest++ = low[(size_t)(*data++ & 0x0f)];
}
return dest;
}
Once p has already moved beyond buf + 1024, these writes become stack
out-of-bounds writes. ASAN reports this as AddressSanitizer:
stack-buffer-overflow and identifies buf in
ngtcp2_qlog_parameters_set_transport_params as the overflowing object.
[See GHSA link for PoC]
Impact
------
Vulnerability type:
Stack-based out-of-bounds write (CWE-121 / CWE-787)
Who is impacted:
Deployments that enable qlog callback (qlog->write != NULL) and process
untrusted peer transport parameters.
Patches
-------
ngtcp2 v1.22.1 fixes this vulnerability.
The following commit mitigates this vulnerability:
https://github.com/ngtcp2/ngtcp2/commit/708a7640c1f48fb8ffb540c4b8ea5b4c1dfb8ee5
Workarounds
-----------
Do not turn on qlog on client.
Severity: High - 7.5 / 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
CVE ID: CVE-2026-40170
Weaknesses: CWE-121 Stack-based Buffer Overflow
Credits: @Kherrisan Reporter
Current thread:
- ngtcp2: qlog_parameters_set_transport_params_stack_overflow [CVE-2026-40170] Alan Coopersmith (Apr 17)
