Skip to content

Fix native memory leak in AsAnyMarshaler.ConvertLayoutToNative on exception#126909

Open
Copilot wants to merge 3 commits intomainfrom
copilot/fix-native-memory-leak
Open

Fix native memory leak in AsAnyMarshaler.ConvertLayoutToNative on exception#126909
Copilot wants to merge 3 commits intomainfrom
copilot/fix-native-memory-leak

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 14, 2026

Description

AsAnyMarshaler.ConvertLayoutToNative leaks the Marshal.AllocCoTaskMem-allocated buffer when LayoutTypeConvertToUnmanaged throws — the exception unwinds past the return pNativeHome with no cleanup.

Fix

Wrap the conversion call in a try/catch that frees on failure, matching the defensive pattern already used in sibling code in the same file:

IntPtr pNativeHome = Marshal.AllocCoTaskMem(allocSize);
try
{
    if (IsIn(dwFlags))
        StubHelpers.LayoutTypeConvertToUnmanaged(pManagedHome, (byte*)pNativeHome, ref cleanupWorkList);
}
catch
{
    Marshal.FreeCoTaskMem(pNativeHome);
    throw;
}

Changes

  • src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs: Added try/catch around LayoutTypeConvertToUnmanaged call in ConvertLayoutToNative to free native memory on exception.

Testing

Risk

Low — strictly adds a cleanup path that was previously missing; no behavioral change on the happy path.

Copilot AI requested review from Copilot and removed request for Copilot April 14, 2026 21:31
Copilot AI changed the title [WIP] Fix native memory leak in LayoutImplementation.ConvertToNative Fix native memory leak in AsAnyMarshaler.ConvertLayoutToNative on exception Apr 14, 2026
Copilot AI requested a review from jkoritzinsky April 14, 2026 21:31
@jkoritzinsky jkoritzinsky marked this pull request as ready for review April 14, 2026 21:36
Copilot AI review requested due to automatic review settings April 14, 2026 21:36
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes an exception-path leak in CoreCLR’s AsAnyMarshaler.ConvertLayoutToNative (in System.Private.CoreLib) by ensuring unmanaged memory allocated via Marshal.AllocCoTaskMem is freed if LayoutTypeConvertToUnmanaged throws during layout marshaling.

Changes:

  • Wrap LayoutTypeConvertToUnmanaged in try/catch within ConvertLayoutToNative.
  • Free the CoTaskMem buffer on exception before rethrowing.

Comment thread src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs
Copilot AI review requested due to automatic review settings April 14, 2026 22:57
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes an exception-path native memory leak in AsAnyMarshaler.ConvertLayoutToNative within CoreLib interop marshaling by ensuring native allocations (and any accumulated cleanup work) are released when LayoutTypeConvertToUnmanaged throws.

Changes:

  • Wraps the LayoutTypeConvertToUnmanaged call in ConvertLayoutToNative with a try/catch.
  • On exception, destroys the cleanupWorkList and frees the Marshal.AllocCoTaskMem buffer before rethrowing.

@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/interop-contrib
See info in area-owners.md if you want to be subscribed.

catch
{
StubHelpers.LayoutTypeConvertToUnmanaged(pManagedHome, (byte*)pNativeHome, ref cleanupWorkList);
StubHelpers.DestroyCleanupList(ref cleanupWorkList);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the full clean-up always safe here? I'd assume that there are already clean-up places for this. The FreeCoTaskMem makes sense, but do we really need the StubHelpers.DestroyCleanupList() as well?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't technically "need" the cleanup list cleanup as the only entries (SafeHandle instances) will eventually be finalized, but without this, they'd have a mismatched refcount until finalization.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

AsAnyMarshaler LayoutImplementation.ConvertToNative leaks native memory on exception

5 participants