Skip to content

Document MemorySegment.reinterpret() as two-gate protected in process isolation model#120

Merged
pfirmstone merged 2 commits intocopilot/update-native-invocation-permissionfrom
copilot/fix-reinterpret-method-security-check
Apr 20, 2026
Merged

Document MemorySegment.reinterpret() as two-gate protected in process isolation model#120
pfirmstone merged 2 commits intocopilot/update-native-invocation-permissionfrom
copilot/fix-reinterpret-method-security-check

Conversation

Copy link
Copy Markdown

Copilot AI commented Apr 20, 2026

PROCESS_ISOLATION.md still described MemorySegment.reinterpret() as “module-system gate only” even after the runtime fix added a NativeInvocationPermission check in AbstractMemorySegmentImpl.reinterpretInternal(). This update aligns the isolation documentation with the current two-gate enforcement model.

  • Summary table correction

    • Updated the MemorySegment.reinterpret() row in “Summary — What the Guards Protect”:
      • from: module flag only / residual gap
      • to: NativeInvocationPermission("reinterpret") + module enableNativeAccess / Blocked by DirtyChai
  • Gate 1 scope update

    • Expanded Gate 1 wording from symbol-resolution-only to native entry points.
    • Added MemorySegment.reinterpret(...)AbstractMemorySegmentImpl.reinterpretInternal() to the Gate 1 entry-point table.
  • Example (updated guard expression)

    | Untrusted jar uses `MemorySegment.reinterpret()` | `NativeInvocationPermission("reinterpret")` at `AbstractMemorySegmentImpl.reinterpretInternal()` + Module `enableNativeAccess` flag | **Blocked by DirtyChai** |
Original prompt

Analysis of the Fix

The code in AbstractMemorySegmentImpl.reinterpretInternal() has been updated to add a NativeInvocationPermission guard for MemorySegment.reinterpret() calls.

What Was Fixed

Previously, the reinterpret() method was only protected by the module system's enableNativeAccess flag, leaving it as a "Module-system gate only" vulnerability (as documented in PROCESS_ISOLATION.md line 635).

The fix adds a SecurityManager permission check after the module system check:

private NativeMemorySegmentImpl reinterpretInternal(Class<?> callerClass, long newSize, MemorySessionImpl scope, Consumer<MemorySegment> cleanup) {
    Reflection.ensureNativeAccess(callerClass, MemorySegment.class, "reinterpret", false);
    // NEW: SecurityManager check via NativeInvocationPermission
    SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
        new NativeInvocationPermission("reinterpret").checkGuard(null);
    }
    Utils.checkNonNegativeArgument(newSize, "newSize");
    if (!isNative()) throw new UnsupportedOperationException("Not a native segment");
    Runnable action = cleanupAction(address(), newSize, cleanup);
    return SegmentFactories.makeNativeSegmentUnchecked(address(), newSize, scope, readOnly, action);
}

This brings MemorySegment.reinterpret() into compliance with DirtyChai's two-gate defence-in-depth model for native code access:

  1. Module system gateReflection.ensureNativeAccess() (JVM flag-based)
  2. SecurityManager gateNativeInvocationPermission (policy-auditable)

What Needs Documentation Update

The PROCESS_ISOLATION.md document needs to be updated to reflect that this attack path is now "Blocked by DirtyChai" instead of "Module-system gate only".

Specifically, line 635 in the "Summary — What the Guards Protect" table must be updated to show the new status and the guard location:

Current (line 635):

| Untrusted jar uses `MemorySegment.reinterpret()` | Module `enableNativeAccess` flag (no SM permission check) | **Module-system gate only** |

Should become:

| Untrusted jar uses `MemorySegment.reinterpret()` | `NativeInvocationPermission("reinterpret")` at `AbstractMemorySegmentImpl.reinterpretInternal()` + Module `enableNativeAccess` flag | **Blocked by DirtyChai** |

Additional context should also be added to describe how the two-gate model now covers this attack path, similar to the pattern documented for SymbolLookup and SystemLookup.

Files to Update

  1. PROCESS_ISOLATION.md — Update the "Summary — What the Guards Protect" table (line 635)
  2. PROCESS_ISOLATION.md — Update or add to the "Gate 1" section to document AbstractMemorySegmentImpl.reinterpretInternal() as a guarded entry point

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: This attack path, Untrusted jar uses MemorySegment.reinterpret() Module enableNativeAccess flag (no SM permission check) Module-system gate only, how effective is it?

Assistant: I'll analyze the security effectiveness of the module-system gate in the context of this attack path. Let me first examine the document you've referenced.

Assistant: Based on the document you've provided, I can analyze the effectiveness of the module-system gate against the MemorySegment.reinterpret() attack path:

The Gap: Module System Gate Only

According to the document (line 635), the attack path where untrusted code uses MemorySegment.reinterpret() is:

Untrusted jar uses MemorySegment.reinterpret() | Module enableNativeAccess flag (no SM permission check) | Module-system gate only

This is a residual vulnerability because:

Why This Is Concerning

  1. No SecurityManager enforcement — The document explicitly states there is "no SM permission check" for MemorySegment.reinterpret(). The only gate is the module system's enableNativeAccess flag.

  2. Module system gap in default mode — The module-system's three modes (lines 542–546) are:

    • ALLOW — no restriction
    • WARN — warning printed, access granted (default)
    • DENYIllegalCallerException if module not listed

    In the default WARN mode, access is granted despite the warning.

  3. Untrusted code can reinterpret native memory — Via MemorySegment.reinterpret(), untrusted code can:

    • Reinterpret a pointer from one segment type to another
    • Bypass the SymbolLookup / SymbolFinder gates (which fire earlier in the chain)
    • Access already-loaded native library memory without any policy-based permission check

Effectiveness Analysis

The module-system gate is incomplete in isolation:

Factor Assessment
Blocks at load time? No — reinterpretation happens at call time, not load time
Requires explicit policy grant? No — depends only on module flags, not DirtyChai policy
Stops untrusted code? Only if `-...

This pull request was created from Copilot chat.

Copilot AI changed the title [WIP] Fix security vulnerability in reinterpret method Document MemorySegment.reinterpret() as two-gate protected in process isolation model Apr 20, 2026
Copilot AI requested a review from pfirmstone April 20, 2026 21:55
Copy link
Copy Markdown
Owner

@pfirmstone pfirmstone left a comment

Choose a reason for hiding this comment

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

Excellent.

@pfirmstone pfirmstone marked this pull request as ready for review April 20, 2026 21:58
@pfirmstone pfirmstone merged commit 1df7c21 into copilot/update-native-invocation-permission Apr 20, 2026
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.

2 participants