fix(remote): make Ctrl-C interrupt blocking getaddrinfo() (#2540)#2728
Open
ChrisJr404 wants to merge 1 commit intoGallopsled:devfrom
Open
fix(remote): make Ctrl-C interrupt blocking getaddrinfo() (#2540)#2728ChrisJr404 wants to merge 1 commit intoGallopsled:devfrom
ChrisJr404 wants to merge 1 commit intoGallopsled:devfrom
Conversation
…#2540) socket.getaddrinfo() holds the GIL during the libc DNS round-trip and on glibc swallows SIGINT, so a hung resolver leaves remote() unkillable until the kernel timeout. Per @Arusekk's suggestion in Gallopsled#2540, swap SIGINT to SIG_DFL only for the duration of the resolution call, then restore the previous handler. Restricted to the main thread (where signal handlers are settable); a no-op everywhere else. Closes Gallopsled#2540
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.
Closes #2540.
What
pwnlib.tubes.remote.remote(host, port)callssocket.getaddrinfo()to resolvehost. On glibc,getaddrinfoholds the GIL during the libc DNS round-trip and swallows SIGINT, so a hung resolver leaves the script unkillable from Ctrl-C until the kernel-level resolver timeout (often ~30s).This PR follows the workaround @Arusekk suggested in the issue thread: swap the SIGINT handler to
SIG_DFLfor the duration of the resolution call, then restore the original handler.remote._connectnow wraps thesocket.getaddrinfo(...)call in this context.Why
Quoted from the issue's main reporter (@tesuji):
And from @Arusekk:
That's exactly what this does, scoped narrowly to the resolver call so it doesn't perturb anything else.
Tests
remote()round-trip against a locallisten()socket still passes (resolution to a literal IP is instantaneous)._interruptible_blockswap+restore verified directly:signal.getsignal(SIGINT)isSIG_DFLinside, equal to the original handler outside.Notes
remote().pwnlib.tubes.remote.remote._connect; if a similar hang ever shows up in another tube's resolver call it can reuse_interruptible_block(or be lifted into a shared module).