NULL dereference in experimental QUIC implementation requires careful handling of initialization order.
The issue involves a NULL dereference in the experimental QUIC implementation when `Session::UpdateDataStats()` is called before `impl_` is initialized. The fix requires ensuring proper initialization order or adding null checks, but working with experimental features adds complexity.
Node.js v25.4.0
Debian 12 Bookworm (Chromebook Crostini)
quic (src/quic/session.cc)
import { connect } from "node:quic";
connect("139.162.123.134:443", {
sni: "nghttp2.org",
alpn: "h3-29",
endpoint: { address: "0.0.0.0:0" },
handshakeTimeout: 5000,
});
setInterval(() => {}, 1000).unref?.();
Run the script with experimental QUIC enabled:
node --experimental-quic test.mjs
Observe that the process crashes with SIGSEGV shortly after printing the “connect” line (no JS exception is raised).
Optional (to confirm the root cause with gdb):
gdb --args node --experimental-quic test.mjs
In gdb, set a temporary breakpoint at node::quic::Session::UpdateDataStats() (or the resolved address) and run:
info functions UpdateDataStats
tbreak *0xaf54e0 # replace with the address shown by the previous command
run
When the breakpoint hits, inspect this->impl_ (offset +0x88 on my build):
info registers rdi
x/gx $rdi+0x88
It shows 0x0 (NULL), and execution later crashes when UpdateDataStats() dereferences it.
The crash is deterministic in my environment.
It reproduces every time I run:
node --experimental-quic test.mjs
There is no need for repeated attempts; the process consistently crashes shortly after initiating the QUIC connection.
The crash occurs during early connection/handshake processing, specifically when Session::Application::SendPendingData() invokes Session::UpdateDataStats() while impl_ is still nullptr.
At this point, the required condition appears to be:
UpdateDataStats() being called before Session::impl_ has been initialized.
Further testing across different Node versions may help determine whether this is a regression or long-standing issue in the experimental QUIC implementation.
Claim this issue to let others know you're working on it. You'll earn 20 points when you complete it!