Repository navigation
net_io: pass the fd count, not the array size, to anetTcpServer - #199
Merged
Merged
Conversation
serviceListen() declares int newfds[16] and passes sizeof (newfds) as the maximum number of descriptors anetTcpServer() may store. That is 64, so a --net-bind-address hostname that resolves to more than 16 addresses makes the bind loop write up to 64 ints into a 16-int stack array: 192 bytes of stack corruption. Pass the array capacity instead. Verified with a getaddrinfo interposer that returns 20 addresses: ASan reports a stack-buffer-overflow in anetTcpServer() before the change and nothing after it, the listener still starts on the first 16 addresses.
wiedehopf
approved these changes
Nov 2, 2026
Owner
|
And it only allows 16 addresses?! |
Contributor
Author
|
Probably 16 are enough, if not: #200 |
Owner
|
already changed a bit of code around, that really doesn't need a PR ;p |
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.
Summary
serviceListen()declaresint newfds[16]and passessizeof (newfds)toanetTcpServer()as the maximum number of descriptors it may store. That argument is a count, not a size: it is 64. Ifgetaddrinfo()returns more than 16 addresses for whichbind()succeeds, the loop inanetTcpServer()writes up to 64 ints into the 16-int stack array.Impact
--net-bind-addressis passed togetaddrinfo()as the node name, so any hostname is accepted (the help text says<ipaddr>, nothing validates it). A name with more than 16 addresses overflowsnewfdsby up to 192 bytes on the stack while the network services are initialized. The overflow stops whenbind()fails, so it needs a hostname with many bindable addresses; with one it is a remote-ish configuration crash/corruption, not a theoretical one.Repro
With an interposer that returns 20 addresses for
many.example(DYLD_INTERPOSEon macOS,LD_PRELOADon Linux; each entry on its own port so everybind()succeeds):Fix
Pass the array capacity,
sizeof (newfds) / sizeof (newfds[0]), instead of the array size in bytes. The listener then uses at most the first 16 addresses, as intended.Verification
anetTcpServer()called fromserviceListen().39123: Beast TCP input portis printed and readsb runs normally (exits cleanly with--auto-exit).