Repository navigation
dgram: reject null bytes in address before queueing - #67064
Open
philipsorensen wants to merge 1 commit into
Open
philipsorensen wants to merge 1 commit into
philipsorensen wants to merge 1 commit into
Conversation
On a socket that is not bound yet, `send()` and `connect()` queue the operation until the implicit bind completes. Since `dns.lookup()` started rejecting hostnames with null bytes, the queued lookup throws from inside the 'listening' event. The error then bypasses the caller's try/catch, the callback and the 'error' listener, and the process exits. Validate the address for null bytes before anything is queued, so the error is thrown synchronously whether or not the socket is bound. Refs: nodejs@7dafafa24247 Signed-off-by: Philip Sørensen <git@ppsa.dk>
Collaborator
|
Review requested:
|
Contributor
|
Welcome to Node.js, and thank you for your first contribution! Before review, please take a moment to read:
Please make sure every commit is signed off. For a first pull request, GitHub Actions require collaborator approval and Jenkins CI must be started by a collaborator or triager, so an initial wait is normal. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #67064 +/- ##
=======================================
Coverage 90.65% 90.65%
=======================================
Files 797 797
Lines 278268 278321 +53
Branches 53517 53524 +7
=======================================
+ Hits 252261 252311 +50
+ Misses 16386 16377 -9
- Partials 9621 9633 +12
🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Since 7dafafa24247 (CVE-2026-48930),
dns.lookup()throws synchronously for a hostname that contains a null byte.On a dgram socket that isn't bound yet,
send()andconnect()only check the address withvalidateString(). They then bind implicitly and queue the operation. The queued lookup runs inside the socket's'listening'emit, so the throw happens there. It bypasses the caller's try/catch, the callback and the'error'listener, and the process exits. Anything else queued on the socket is lost. On a bound socket the same call throws synchronously and can be caught.This reproduces on v22.23.x, v24.21.0+, v26.12.1 and main. Before the CVE fix, the packet went to the truncated host instead.
This PR uses
validateStringWithoutNullBytes()for the address insend()andconnect(), before anything is bound or queued (connect, send). The error is now the same synchronousERR_INVALID_ARG_VALUEwhether or not the socket is bound, which matches whatdnsandnetthrow for this input.The new test covers
send()andconnect()on an unbound socket, and checks that the socket still works afterwards. It fails without the change.Not included, and I'm happy to follow up separately if wanted:
bind(port, 'a\0b')throws, but leaves the socket in the binding state.http.Agenthas a similar deferred throw when a queued request (becausemaxTotalSocketsis reached) has a host with a null byte.