quic: reject zero addressLRUSize · nodejs/node@84ecb21 · GitHub
Skip to content

Commit 84ecb21

Browse files
christianaurichzmaduh95
authored andcommitted
quic: reject zero addressLRUSize
SocketAddressLRU::Upsert always inserts an entry before evicting down to max_size_. With max_size_ == 0, it evicts the entry it just inserted and then accesses the now-missing key via map_[address]->second. operator[] recreates the key with a default-constructed std::list iterator, which is then dereferenced. This is undefined behavior, observed as a SIGSEGV in Endpoint::Receive on the first UDP packet accepted by a QuicEndpoint constructed with { addressLRUSize: 0 }. SocketAddressLRU has no useful semantics for a zero-capacity cache, and Upsert's callers rely on it returning a valid pointer. Reject 0 (and 0n) at the options-parsing boundary instead of changing Upsert's contract. Signed-off-by: Christian Aurich <christian.aurichzm@gmail.com> PR-URL: #65827 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tim Perry <pimterry@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
1 parent 830ca7d commit 84ecb21

3 files changed

Lines changed: 14 additions & 3 deletions

File tree

‎doc/api/quic.md‎

Lines changed: 2 additions & 2 deletions

‎src/quic/endpoint.cc‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,17 @@ Maybe<Endpoint::Options> Endpoint::Options::From(Environment* env,
249249
return Nothing<Options>();
250250
}
251251

252+
// SocketAddressLRU::Upsert requires a positive capacity. With max_size_ ==
253+
// 0, the newly inserted entry is immediately evicted, and the final
254+
// map_[address] creates a default list iterator that is then
255+
// dereferenced, causing UB (observed as a SIGSEGV in Endpoint::Receive on
256+
// the first accepted connection).
257+
if (options.address_lru_size == 0) {
258+
THROW_ERR_INVALID_ARG_VALUE(
259+
env, "The addressLRUSize option must be greater than 0");
260+
return Nothing<Options>();
261+
}
262+
252263
Local<Value> address;
253264
if (!params->Get(env->context(), env->address_string()).ToLocal(&address)) {
254265
return Nothing<Options>();

‎test/parallel/test-quic-internal-endpoint-options.mjs‎

Lines changed: 1 addition & 1 deletion

0 commit comments

Comments
 (0)