fix: don't UB if EncryptedStreamSocket Negotiate() is entered with no expected bytes - #779
Merged
mrjimenez merged 1 commit intoJun 1, 2026
Conversation
…-project#778) mifritscher2 hit a debug-build assert switching ed2k servers: /home/x/code/amule/src/EncryptedStreamSocket.cpp(437): assert "m_nReceiveBytesWanted > 0" failed in Negotiate(). bt: CServerSocket::OnReceive -> CEMSocket::OnReceive -> CEncryptedStreamSocket::Read -> Negotiate -> wxASSERT CEncryptedStreamSocket::Read() unconditionally calls Negotiate() whenever the socket sits in ECS_NEGOTIATING and bytes arrive. The negotiation state machine consumes bytes in chunks of m_nReceiveBytesWanted; when that counter hits 0 the inner loop exits and the function returns either via ONS_COMPLETE (advancing to ECS_ENCRYPTING) or via a state transition that resets the counter to a fresh positive expectation. There is a window where the socket can stay in ECS_NEGOTIATING with m_nReceiveBytesWanted == 0 -- the obvious trigger is the user switching servers while the kernel still has buffered bytes for the previous half-negotiated connection. The next OnReceive lands in Read(), Read() dispatches to Negotiate(), and we hit the precondition assert. The asserted precondition is a real bug shape: walking into the while loop with m_nReceiveBytesWanted == 0 lets std::min(nLen - nRead, 0) return 0 forever (infinite loop bails via ONS_COMPLETE check, but the state math is bogus). wxASSERT compiles to a no-op in release builds, so the production path is undefined behaviour rather than a clean abort. Same shape as the wxASSERT-as-precondition cluster the clang-tidy baseline (amule-project#770) and amule-project#772 already converted to wxCHECK_* elsewhere -- just on a site amule-project#772 did not reach. Switch this site to wxCHECK_MSG with a -1 sentinel return. Both callers in Read() already check for nRead == (uint32_t)(-1) and short-circuit to "encryption read error" -> abort the connection. Debug builds still abort (wxCHECK_MSG asserts in debug); release builds now drop the connection cleanly instead of UB'ing forward.
This was referenced May 31, 2026
|
I applied that patch - can last some days/week until I hit this again... |
Contributor
|
Should we merge or we wait? |
Contributor
Author
|
I think it's safe to merge it |
1 task
got3nks
added a commit
to got3nks/amule
that referenced
this pull request
Jun 4, 2026
…ndex Adds 55+ merged PRs to the 3.0.0 changelog since the last update (amule-project#747, 2026-05-27). Narrative additions cover: - Packaging: expanded the top list to include the macOS per-arch .app bundles and the Windows NSIS installer alongside the existing AppImage / Flatpak / .dmg / .zip entries. New bullets for amule-project#785 (alc/alcc/cas/wxcas everywhere + Windows amuleweb), amule-project#794 (.dmg amuleweb path), amule-project#789 (<OS>-<arch> artifact naming), amule-project#780 / amule-project#796 (Windows DPI + comctl32 manifest), amule-project#784 (FHS share/amule paths). - Bug Fixes & Stability: post-amule-project#744 fixes including EC notification leak (amule-project#797), big-library scaling (amule-project#736, amule-project#840 superseding amule-project#728), amulegui ghost entries (amule-project#810, amule-project#819, amule-project#841, amule-project#824, amule-project#830, amule-project#760), PartFile early hash (amule-project#762), server protocol fixes (amule-project#835, amule-project#788, amule-project#721, amule-project#787), crypto stream UB (amule-project#779), UAF prevention (amule-project#756), Kad rotation (amule-project#795, amule-project#799/amule-project#805), GTK warning silencing (amule-project#833, amule-project#826/amule-project#836), and the clang-tidy worklist (amule-project#770, amule-project#772-amule-project#774). - Translations: late-cycle wave covering French/Turkish manpages (amule-project#753/amule-project#754/amule-project#776), Galician (amule-project#763), Slovenian (amule-project#771), pt-BR (amule-project#768/amule-project#775/amule-project#812), French (amule-project#811), plus man-page tooling for date+version drift (amule-project#802). - Contributors: added ngosang for UX feedback on the late-3.0 cycle (amule-project#817/amule-project#818/amule-project#821/amule-project#828/amule-project#844) and ongoing work on the user-facing manual at amule-org.github.io. - Merged PRs flat index: extended with amule-project#746-amule-project#845 + amule-project#841.
got3nks
added a commit
to got3nks/amule
that referenced
this pull request
Jun 4, 2026
…ndex Adds 55+ merged PRs to the 3.0.0 changelog since the last update (amule-project#747, 2026-05-27). Narrative additions cover: - Packaging: expanded the top list to include the macOS per-arch .app bundles and the Windows NSIS installer alongside the existing AppImage / Flatpak / .dmg / .zip entries. New bullets for amule-project#785 (alc/alcc/cas/wxcas everywhere + Windows amuleweb), amule-project#794 (.dmg amuleweb path), amule-project#789 (<OS>-<arch> artifact naming), amule-project#780 / amule-project#796 (Windows DPI + comctl32 manifest), amule-project#784 (FHS share/amule paths). - Bug Fixes & Stability: post-amule-project#744 fixes including EC notification leak (amule-project#797), big-library scaling (amule-project#736, amule-project#840 superseding amule-project#728), amulegui ghost entries (amule-project#810, amule-project#819, amule-project#841, amule-project#824, amule-project#830, amule-project#760), PartFile early hash (amule-project#762), server protocol fixes (amule-project#835, amule-project#788, amule-project#721, amule-project#787), crypto stream UB (amule-project#779), UAF prevention (amule-project#756), Kad rotation (amule-project#795, amule-project#799/amule-project#805), GTK warning silencing (amule-project#833, amule-project#826/amule-project#836), and the clang-tidy worklist (amule-project#770, amule-project#772-amule-project#774). - Translations: late-cycle wave covering French/Turkish manpages (amule-project#753/amule-project#754/amule-project#776), Galician (amule-project#763), Slovenian (amule-project#771), pt-BR (amule-project#768/amule-project#775/amule-project#812), French (amule-project#811), plus man-page tooling for date+version drift (amule-project#802). - Contributors: added ngosang for UX feedback on the late-3.0 cycle (amule-project#817/amule-project#818/amule-project#821/amule-project#828/amule-project#844) and ongoing work on the user-facing manual at amule-org.github.io. - Merged PRs flat index: extended with amule-project#746-amule-project#845 + amule-project#841.
mrjimenez
pushed a commit
that referenced
this pull request
Jun 4, 2026
Adds 55+ merged PRs to the 3.0.0 changelog since the last update (#747, 2026-05-27). Narrative additions cover: - Packaging: expanded the top list to include the macOS per-arch .app bundles and the Windows NSIS installer alongside the existing AppImage / Flatpak / .dmg / .zip entries. New bullets for #785 (alc/alcc/cas/wxcas everywhere + Windows amuleweb), #794 (.dmg amuleweb path), #789 (<OS>-<arch> artifact naming), #780 / #796 (Windows DPI + comctl32 manifest), #784 (FHS share/amule paths). - Bug Fixes & Stability: post-#744 fixes including EC notification leak (#797), big-library scaling (#736, #840 superseding #728), amulegui ghost entries (#810, #819, #841, #824, #830, #760), PartFile early hash (#762), server protocol fixes (#835, #788, #721, #787), crypto stream UB (#779), UAF prevention (#756), Kad rotation (#795, #799/#805), GTK warning silencing (#833, #826/#836), and the clang-tidy worklist (#770, #772-#774). - Translations: late-cycle wave covering French/Turkish manpages (#753/#754/#776), Galician (#763), Slovenian (#771), pt-BR (#768/#775/#812), French (#811), plus man-page tooling for date+version drift (#802). - Contributors: added ngosang for UX feedback on the late-3.0 cycle (#817/#818/#821/#828/#844) and ongoing work on the user-facing manual at amule-org.github.io. - Merged PRs flat index: extended with #746-#845 + #841.
got3nks
added a commit
to got3nks/amule
that referenced
this pull request
Aug 3, 2026
…oject#779) AddDebugLogLineN passes its category straight to CLogger::IsEnabled, whose index check rejects anything below zero and hits wxFAIL. logStandard is the -1 sentinel meaning "not a debug category" -- what AddLogLineN passes -- so asking whether it is enabled is invalid by construction. The splash always finishes, so this fired on every Debug monolithic launch, and assertions block by default: the GUI could not start without dismissing a dialog first. Release builds compile AddDebugLogLineN away entirely and were unaffected. Use logGeneral, keeping the line at debug level as intended.
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
Fixes #778.
CEncryptedStreamSocket::Negotiate()opens withwxASSERT(m_nReceiveBytesWanted > 0)— a precondition that the negotiation state machine still expects more handshake bytes. mifritscher2 hit it when switching ed2k servers: the kernel still had buffered data for the half-negotiated connection,Read()dispatched intoNegotiate()while the counter was already 0, and the debug build aborted.The asserted precondition is load-bearing — the
whileloop below assumes a positive count and the math is bogus otherwise.wxASSERTis a no-op in release, so production was undefined behaviour rather than a clean abort. Same shape as thewxASSERT-as-precondition cluster the baseline config in #770 and #772 already converted — just on a site #772 didn't reach.Fix
Switch the
wxASSERTtowxCHECK_MSGreturning-1. Both call sites inRead()already treat(uint32_t)(-1)as the encryption-read-error sentinel and bail out cleanly (lines 249-260 and 298-301). Debug builds keep aborting on first mis-use; release builds now drop the connection instead of UB-ing forward.Out of scope
The deeper question of why
Negotiate()is reachable withm_nReceiveBytesWanted == 0in the first place — i.e. whether the server-switch teardown path should drain the kernel buffer before going toECS_NEGOTIATINGor whether the state machine itself has a missing transition — is left for a follow-up. The negotiation state machine is delicate enough that I'd want a reproducer before changing transition logic; this PR makes the production path safe in the meantime.Test plan
wxCHECK_MSGshort-circuits identically towxASSERTwhen the precondition holdsSame pattern as the Logger / UserEvents fixes that landed in #772.