Repository navigation
fix(rs_port): correct MetaCallException ownership and cloning - #948
Open
AshutoshSharma-pixel wants to merge 1 commit into
Open
AshutoshSharma-pixel wants to merge 1 commit into
AshutoshSharma-pixel wants to merge 1 commit into
Conversation
This branch has not been deployed
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 #809 (partially, focusing specifically on
MetaCallExceptionmemory safety and RUSTSEC-2026-0156).This PR fixes severe memory-safety vulnerabilities in the Rust port's
MetaCallExceptionwrapper:MetaCallException::new():MetaCallException::new()created a stack-allocatedmetacall_exception_typestruct and passed its pointer tometacall_value_create_exception(&mut exception_struct as *mut _ as *mut c_void). When the stack frame exited, the C exception retained a dangling pointer to escaped stack memory. When dropped, C calledfree()on stack addresses, causing undefined behavior, bad-free aborts, and memory corruption.metacall_error_throw(), formatting the error message safely via"%s".metacall_error_throw()returns an owned temporary throwable value wrapping the exception.metacall_throwable_value(), deep-copy it usingmetacall_value_copy()(which allocates a new value header and increments the C exception reference count), and immediately destroy the temporary throwable withmetacall_value_destroy().new_raw():metacall_error_from_value().MetaCallExceptionnow stores ownedStringfields (message,label,stacktrace) rather than raw pointers into C memory, preventing use-after-free and dangling pointer access.Cloneperformed a shallow copy (self.valuewas duplicated whileleakwas set totrue), causing use-after-free once the original instance was dropped.metacall_value_copy(self.value). Each clone now owns its ownmetacall_valuepointer and releases it onDrop. Clones can outlive or be dropped in any order without memory safety issues.Scope Boundary
MetaCallExceptionand its integration tests.unsafe fn new_raw) across all wrappers (reserved for subsequent PRs).MetaCallClass,MetaCallObject,MetaCallFunction,MetaCallThrowable,MetaCallFuture,MetaCallPointer).Verification & Testing
Runtime verification was executed inside a containerized Debian environment based on
metacall/core:devunder x86_64 architecture matching MetaCall CI:cargo build --verbosepassed cleanly with 0 errors.cargo clippy -- -D warnings: Passed (0 warnings).cargo fmt --check: Passed cleanly.cargo test --test metacall_exception_test -- --test-threads=1 --nocapturepassed.test_exception_new_and_drop)test_exception_clone_outlives_original)test_exception_original_outlives_clone)test_exception_repeated_cloning)test_exception_nodejs_load)initialize()RAII runtime guard.cargo test -- --test-threads=1passed: 6/6 test suites passed (100% pass rate).valgrind --leak-check=fullagainst the compiled test binary.MetaCallExceptionor its C lifecycle routines.