Skip to content

Fix #632: [Bug] Heap-use-after-free in chaiscript::str_less::operator() due to race condition#651

Closed
leftibot wants to merge 1 commit into
ChaiScript:developfrom
leftibot:fix/issue-632-bug-heap-use-after-free-in-chaiscript-st
Closed

Fix #632: [Bug] Heap-use-after-free in chaiscript::str_less::operator() due to race condition#651
leftibot wants to merge 1 commit into
ChaiScript:developfrom
leftibot:fix/issue-632-bug-heap-use-after-free-in-chaiscript-st

Conversation

@leftibot
Copy link
Copy Markdown
Contributor

Automated fix by @leftibot.

What changed

Fix #632: Join async threads before engine destruction to prevent use-after-free
The heap-use-after-free was caused by a race condition where async threads
continued accessing the engine's shared state (global objects map) after the
main thread began destroying the Dispatch_Engine. The fix moves the async
function registration from the stdlib module into ChaiScript_Basic, where it
can track spawned threads via Dispatch_Engine. The engine's destructor now
joins all outstanding async threads before destroying shared data structures.
Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com

Files

 CMakeLists.txt                                    |  4 +++
 include/chaiscript/chaiscript_stdlib.hpp          |  3 --
 include/chaiscript/dispatchkit/dispatchkit.hpp    | 35 +++++++++++++++++++
 include/chaiscript/language/chaiscript_engine.hpp | 18 ++++++++++
 unittests/async_engine_lifetime.chai              | 18 ++++++++++
 unittests/async_lifetime_test.cpp                 | 42 +++++++++++++++++++++++
 6 files changed, 117 insertions(+), 3 deletions(-)

Closes #632

Triggered by @lefticus.

…revent use-after-free

The heap-use-after-free was caused by a race condition where async threads
continued accessing the engine's shared state (global objects map) after the
main thread began destroying the Dispatch_Engine. The fix moves the async
function registration from the stdlib module into ChaiScript_Basic, where it
can track spawned threads via Dispatch_Engine. The engine's destructor now
joins all outstanding async threads before destroying shared data structures.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
leftibot added a commit to leftibot/ChaiScript that referenced this pull request Apr 11, 2026
…revent heap-use-after-free

Issues ChaiScript#632 and ChaiScript#636 (PRs ChaiScript#651 and ChaiScript#653) both stem from the same root cause: async
threads spawned via async() can outlive the Dispatch_Engine, accessing shared state
(global objects map, type maps) after it has been destroyed. The fix moves async()
registration from the stdlib module into ChaiScript_Basic, where spawned threads are
tracked via Dispatch_Engine. The engine's destructor now joins all outstanding async
threads before destroying shared data structures.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@lefticus
Copy link
Copy Markdown
Member

closing in favor of #655

@lefticus lefticus closed this Apr 11, 2026
lefticus pushed a commit that referenced this pull request Apr 11, 2026
…656)

* Fix #655: Join async threads before engine destruction to prevent heap-use-after-free

Issues #632 and #636 (PRs #651 and #653) both stem from the same root cause: async
threads spawned via async() can outlive the Dispatch_Engine, accessing shared state
(global objects map, type maps) after it has been destroyed. The fix moves async()
registration from the stdlib module into ChaiScript_Basic, where spawned threads are
tracked via Dispatch_Engine. The engine's destructor now joins all outstanding async
threads before destroying shared data structures.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Address review: follow rule of 5, explicitly default move operations

Requested by @lefticus in PR #656 review.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: leftibot <leftibot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Heap-use-after-free in chaiscript::str_less::operator() due to race condition

2 participants