oracle / graal

GraalVM compiles Java applications into native executables that start instantly, scale fast, and use fewer compute resources 🚀
https://www.graalvm.org
Other
20.34k stars 1.63k forks source link

[Native Image] Incompatible with macOS App Sandbox #9954

Open sgammon opened 1 day ago

sgammon commented 1 day ago

Describe the Issue

When building and signing a GraalVM-produced binary for macOS under App Sandbox, the application should work, so long as the developer's code adheres to the rules of the App Sandbox and Hardened Runtime.

Instead, the attached crash is thrown regardless of entitlement state.

Using the latest version of GraalVM can resolve many issues.

GraalVM Version

java --version:

java version "23" 2024-09-17
Java(TM) SE Runtime Environment Oracle GraalVM 23+37.1 (build 23+37-jvmci-b01)
Java HotSpot(TM) 64-Bit Server VM Oracle GraalVM 23+37.1 (build 23+37-jvmci-b01, mixed mode, sharing)

native-image --version

native-image 23 2024-09-17
GraalVM Runtime Environment Oracle GraalVM 23+37.1 (build 23+37-jvmci-b01)
Substrate VM Oracle GraalVM 23+37.1 (build 23+37, serial gc, compressed references)

Operating System and Version

Darwin 24.1.0 Darwin Kernel Version 24.1.0: Mon Sep 30 00:07:01 PDT 2024; root:xnu-11215.40.63~39/RELEASE_ARM64_T6020 arm64

Diagnostic Flag Confirmation

Run Command

./sample

Expected Behavior

I expect the program to run and print "Hello World"

Actual Behavior

It unconditionally crashes instead:

Util_jdk_internal_misc_Signal.ensureInitialized: CSunMiscSignal.create() failed.  errno: 1  Operation not permitted
Fatal error: Util_jdk_internal_misc_Signal.ensureInitialized: CSunMiscSignal.open() failed.

See Run-Time Log Output for full crash-trace.

Steps to Reproduce

  1. Build any GraalVM Native Image binary on macOS (I'm on latest, but App Sandbox was introduced in Catalina)
  2. Prepare an Info.plist
  3. Add arguments to your -H:NativeLinkerFlags to embed the PList section
  4. Sign the binary with entitlements which enable App Sandbox
  5. Run the binary

Additional Context

Step 1:

Entrypoint.java

package repro;

public class Entrypoint {
  public static void main(String[] args) {
    System.out.println("Hello World");
  }
}

Compile to native binary and sign (0) add Entrypoint.java, Info.plist, and Entitlements.plist to a directory. you will also need signing credentials from Apple Developer.

mkdir repro && javac Entrypoint.java && mv Entrypoint.class repro

# build native
native-image \
    -H:+UnlockExperimentalVMOptions \
    -H:+InstallExitHandlers \
    -H:NativeLinkerOption=-sectcreate \
    -H:NativeLinkerOption=__TEXT \
    -H:NativeLinkerOption=__info_plist \
    -H:NativeLinkerOption=$(pwd)/Info.plist \
    -cp . \
    repro.Entrypoint \
    sample

# binary runs
./sample

# now sign it but without app sandbox enabled (only Hardened Runtime)
codesign \
    --sign "Developer ID ..." \
    -o runtime \
    --timestamp \
    sample

# binary runs
./sample

# now sign it with app sandbox enabled
codesign \
    --sign "Developer ID ..." \
    -o runtime \
    --timestamp \
    --entitlements Entitlements.plist \
    sample

# binary crashes
./sample

Info.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>English</string>
    <key>CFBundleIdentifier</key>
    <string>some.bundle.identifier</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>somename</string>
</dict>
</plist>

Entitlements.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.security.app-sandbox</key>
    <true/>
    <key>com.apple.security.cs.allow-jit</key>
    <true/>
    <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
    <true/>
    <key>com.apple.security.cs.disable-library-validation</key>
    <true/>
    <key>com.apple.security.cs.allow-dyld-environment-variables</key>
    <true/>
    <key>com.apple.security.cs.debugger</key>
    <true/>
</dict>
</plist>

Run-Time Log Output and Error Messages

Expand for full crash trace
Util_jdk_internal_misc_Signal.ensureInitialized: CSunMiscSignal.create() failed.  errno: 1  Operation not permitted
Fatal error: Util_jdk_internal_misc_Signal.ensureInitialized: CSunMiscSignal.open() failed.

Printing instructions (ip=0x0000000104e684b8):
  0x0000000104e683b8: 0xc1 0xdf 0x9f 0x52 0xc1 0xdf 0xaf 0x72 0x81 0xcf 0x00 0xb9 0xe1 0x03 0x02 0xaa
  0x0000000104e683c8: 0xe2 0x03 0x03 0xaa 0xbd 0x8d 0xfd 0x97 0x1f 0x20 0x03 0xd5 0xcc 0xcc 0xcc 0xcc
  0x0000000104e683d8: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xff 0xc3 0x00 0xd1 0xfd 0x7b 0x02 0xa9
  0x0000000104e683e8: 0xe0 0x17 0x40 0xf9 0xe1 0x03 0x00 0x32 0x88 0x43 0x03 0x91 0x01 0xfd 0x9f 0x88
  0x0000000104e683f8: 0xe1 0x03 0x40 0xb2 0x81 0x07 0x00 0xf9 0xc1 0xdf 0x9f 0x52 0xc1 0xdf 0xaf 0x72
  0x0000000104e68408: 0x81 0xcf 0x00 0xb9 0xe1 0x27 0x83 0x52 0x81 0x04 0xa0 0x72 0x61 0x0f 0x01 0x8b
  0x0000000104e68418: 0xe2 0x03 0x1b 0xaa 0xa9 0x8d 0xfd 0x97 0x1f 0x20 0x03 0xd5 0xcc 0xcc 0xcc 0xcc
  0x0000000104e68428: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xff 0xc3 0x00 0xd1 0xfd 0x7b 0x02 0xa9
  0x0000000104e68438: 0xe0 0x17 0x40 0xf9 0xe1 0x03 0x00 0x32 0x88 0x43 0x03 0x91 0x01 0xfd 0x9f 0x88
  0x0000000104e68448: 0xe1 0x03 0x40 0xb2 0x81 0x07 0x00 0xf9 0xc1 0xdf 0x9f 0x52 0xc1 0xdf 0xaf 0x72
  0x0000000104e68458: 0x81 0xcf 0x00 0xb9 0xe1 0x60 0x9f 0x52 0x61 0x04 0xa0 0x72 0x61 0x0f 0x01 0x8b
  0x0000000104e68468: 0xe2 0x03 0x1b 0xaa 0x95 0x8d 0xfd 0x97 0x1f 0x20 0x03 0xd5 0xcc 0xcc 0xcc 0xcc
  0x0000000104e68478: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xff 0xc3 0x00 0xd1 0xfd 0x7b 0x02 0xa9
  0x0000000104e68488: 0xe1 0x03 0x00 0xaa 0xe0 0x17 0x40 0xf9 0xe2 0x03 0x00 0x32 0x88 0x43 0x03 0x91
  0x0000000104e68498: 0x02 0xfd 0x9f 0x88 0xe2 0x03 0x40 0xb2 0x82 0x07 0x00 0xf9 0xc2 0xdf 0x9f 0x52
  0x0000000104e684a8: 0xc2 0xdf 0xaf 0x72 0x82 0xcf 0x00 0xb9 0xe2 0x03 0x1b 0xaa 0x83 0x8d 0xfd 0x97
> 0x0000000104e684b8: 0x1f 0x20 0x03 0xd5 0xcc 0xcc 0xcc 0xcc 0xff 0xc3 0x02 0xd1 0xfd 0x7b 0x0a 0xa9
  0x0000000104e684c8: 0x02 0x01 0x00 0xb4 0x43 0x00 0x40 0xb9 0x7f 0x18 0x00 0x71 0xa3 0x06 0x00 0x54
  0x0000000104e684d8: 0x40 0x01 0x80 0x52 0xfd 0x7b 0x4a 0xa9 0xff 0xc3 0x02 0x91 0xc0 0x03 0x5f 0xd6
  0x0000000104e684e8: 0xe0 0x03 0x5d 0xb2 0xe5 0x03 0x00 0xaa 0xe8 0x03 0x1f 0xaa 0xe8 0x4f 0x00 0xf9
  0x0000000104e684f8: 0xe8 0x03 0x1f 0xaa 0xe8 0x4b 0x00 0xf9 0xe5 0x07 0x08 0xa9 0xe6 0x43 0x01 0x91
  0x0000000104e68508: 0x67 0x54 0x81 0x52 0x87 0x0a 0xa0 0x72 0x67 0x0f 0x07 0x8b 0xe2 0x03 0x6d 0xb2
  0x0000000104e68518: 0xe0 0x03 0x07 0xaa 0xe1 0x03 0x05 0xaa 0xe3 0x03 0x1f 0x2a 0xe7 0x0f 0x00 0xf9
  0x0000000104e68528: 0xe6 0x3f 0x00 0xf9 0x35 0x9d 0xfe 0x97 0x1f 0x20 0x03 0xd5 0x20 0x03 0x00 0xb4
  0x0000000104e68538: 0xe6 0x3f 0x40 0xf9 0xc0 0x00 0x00 0xf9 0xc5 0x00 0x40 0xf9 0xe5 0x3f 0x00 0xf9
  0x0000000104e68548: 0xe6 0x03 0x01 0x91 0x20 0x57 0x84 0x52 0x80 0x0a 0xa0 0x72 0x60 0x0f 0x00 0x8b
  0x0000000104e68558: 0xe1 0x03 0x05 0xaa 0xe2 0x0f 0x48 0xa9 0xe4 0x03 0x06 0xaa 0xe6 0x3b 0x00 0xf9
  0x0000000104e68568: 0x4e 0x91 0xfe 0x97 0x1f 0x20 0x03 0xd5 0xc0 0x03 0x00 0x34 0xe0 0x67 0x00 0xb9
  0x0000000104e68578: 0xe0 0x0f 0x40 0xf9 0xe1 0x8b 0x47 0xa9 0xa4 0x9c 0xfe 0x97 0x1f 0x20 0x03 0xd5
  0x0000000104e68588: 0xe0 0x67 0x40 0xb9 0xfd 0x7b 0x4a 0xa9 0xff 0xc3 0x02 0x91 0xc0 0x03 0x5f 0xd6
  0x0000000104e68598: 0x20 0x64 0x80 0x52 0xfd 0x7b 0x4a 0xa9 0xff 0xc3 0x02 0x91 0xc0 0x03 0x5f 0xd6
  0x0000000104e685a8: 0x7f 0x08 0x00 0x71 0xab 0x09 0x00 0x54 0x40 0x10 0x41 0xa9 0xe5 0x03 0x5d 0xb2

Top of stack (sp=0x000000016b7ed3a0):
  0x000000016b7ed380: 0x000000030289c1c8 0x000000000289c1c8 0x000000016b7ed9b0 0x0000000104e684b8
> 0x000000016b7ed3a0: 0x0000000000000000 0x14189c02266d00f2 0x000000000000032b 0x000000030289c1c8
  0x000000016b7ed3c0: 0x000000016b7ed9b0 0x0000000104e10698 0x0000000000000000 0x0000000000000000
  0x000000016b7ed3e0: 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x000000030289c1c8
  0x000000016b7ed400: 0x00000003025e3858 0x0000000000000000 0x0000000104e10628 0x000000016b7ed3d0
  0x000000016b7ed420: 0x0000000000000000 0x0000007400000065 0x00000000720d9b1c 0x0000000100000000
  0x000000016b7ed440: 0x000000016b7ed9b0 0x0000000104e11ae0 0x34e63b4167e12cdf 0x0000000000000000
  0x000000016b7ed460: 0x000000016b7ed9b0 0x00000001062fd288 0x0000000000000009 0x00000003011b8970
  0x000000016b7ed480: 0x0000000000000000 0x0000000000000000 0x000000016b7ed9b0 0x00000001067c8b40
  0x000000016b7ed4a0: 0x000000018133a000 0x000000016b7ed868 0x000000016b7ed868 0x0000000000000001
  0x000000016b7ed4c0: 0x000000000000032b 0x00000003011b8970 0x0000000304d01030 0x000000000000002e
  0x000000016b7ed4e0: 0x000000016b7ed9b0 0x00000001067c8a94 0x000000016b7ed408 0x0000000000000010
  0x000000016b7ed500: 0x0000000000000000 0x0000000300000000 0x0000000304d01030 0x00000003011b8970
  0x000000016b7ed520: 0x000000016b7ed9b0 0x000000010630da54 0x0000000000000004 0x0000000302727830
  0x000000016b7ed540: 0x0000000300724598 0x0000000304d01028 0x000000016b7ed9b0 0x0000000104d6a694
  0x000000016b7ed560: 0x000000016b7ed9b0 0x0000000000000000 0x000000016b7ed9b0 0x00000003022dd5b8
  0x000000016b7ed580: 0x000000016b7ed9b0 0x0000000104dc68ec 0x0000000000000001 0x00000003011c03b0

VM thread locals for the failing thread 0x0000000134a04fc0:
  0: JNIThreadLocalEnvironment.jniFunctions = (bytes) 0x000000030187a810
  8: StackOverflowCheckImpl.stackBoundaryTL = (Word) 0x0000000000000001 (1)
  16: Safepoint.safepointRequested = (int) 0x7fff8758 (2147452760)
  20: StatusSupport.statusTL = (int) 0x00000001 (1)
  24: ThreadLocalAllocation.regularTLAB = (bytes) 
    0x0000000134a04fd8: 0x0000000304d00000 0x0000000304d80000
    0x0000000134a04fe8: 0x0000000304d01040 0x0000000000000000
  56: JavaFrameAnchors.lastAnchor = (Word) 0x0000000000000000 (0)
  64: JavaThreads.currentVThreadId = (long) 0x0000000000000001 (1)
  72: PlatformThreads.currentThread = (Object) 0x00000003021e8340
    is an object of type java.lang.Thread
  80: SubstrateDiagnostics.threadOnlyAttachedForCrashHandler = (bytes) 0x0000000000000000
  88: ThreadLocalAllocation.allocatedBytes = (Word) 0x0000000000000000 (0)
  96: VMThreads.IsolateTL = (Word) 0x0000000300000000 (12884901888)
  104: VMThreads.OSThreadHandleTL = (Word) 0x00000001e67cf640 (8161916480)
  112: VMThreads.OSThreadIdTL = (Word) 0x0000000000000103 (259)
  120: VMThreads.StackBase = (Word) 0x000000016b7f0000 (6098452480)
  128: VMThreads.StackEnd = (Word) 0x000000016aff4000 (6090080256)
  136: VMThreads.StartedByCurrentIsolate = (bytes) 0x0000000000000000
  144: VMThreads.nextTL = (Word) 0x0000000000000000 (0)
  152: VMThreads.unalignedIsolateThreadMemoryTL = (Word) 0x0000000134a04fb0 (5177888688)
  160: ExceptionUnwind.currentException = (Object) 0x0000000000000000
  164: JNIObjectHandles.handles = (Object) 0x0000000304d00960
    is an object of type com.oracle.svm.core.handles.ThreadLocalHandles
  168: JNIThreadLocalPendingException.pendingException = (Object) 0x0000000000000000
  172: JNIThreadLocalReferencedObjects.referencedObjectsListHead = (Object) 0x0000000000000000
  176: JNIThreadOwnedMonitors.ownedMonitors = (Object) 0x0000000000000000
  180: NoAllocationVerifier.openVerifiers = (Object) 0x0000000000000000
  184: RecurringCallbackTimer.exception = (Object) 0x0000000000000000
  188: ThreadingSupportImpl.activeTimer = (Object) 0x0000000000000000
  192: ActionOnTransitionToJavaSupport.actionTL = (int) 0x00000000 (0)
  196: ImplicitExceptions.implicitExceptionsAreFatal = (int) 0x00000000 (0)
  200: Safepoint.suspended = (int) 0x00000000 (0)
  204: StackOverflowCheckImpl.yellowZoneStateTL = (int) 0x7efefefe (2130640638)
  208: StatusSupport.safepointBehaviorTL = (int) 0x00000001 (1)
  212: ThreadingSupportImpl.currentPauseDepth = (int) 0x00000000 (0)

Java frame anchors for the failing thread 0x0000000134a04fc0:
  No anchors

Stacktrace for the failing thread 0x0000000134a04fc0 (A=AOT compiled, J=JIT compiled, D=deoptimized, i=inlined):
  i  SP 0x000000016b7ed3a0 IP 0x0000000104e684b8 size=48    com.oracle.svm.core.jdk.VMErrorSubstitutions.shutdown(VMErrorSubstitutions.java:146)
  i  SP 0x000000016b7ed3a0 IP 0x0000000104e684b8 size=48    com.oracle.svm.core.jdk.VMErrorSubstitutions.shouldNotReachHere(VMErrorSubstitutions.java:139)
  A  SP 0x000000016b7ed3a0 IP 0x0000000104e684b8 size=48    com.oracle.svm.core.util.VMError.shouldNotReachHere(VMError.java:90)
  A  SP 0x000000016b7ed3d0 IP 0x0000000104e10698 size=128   com.oracle.svm.core.posix.Util_jdk_internal_misc_Signal.ensureInitialized(SunMiscSubstitutions.java:187)
  A  SP 0x000000016b7ed450 IP 0x0000000104e11ae0 size=80    com.oracle.svm.core.posix.Util_jdk_internal_misc_Signal.numberFromName(SunMiscSubstitutions.java:234)
  i  SP 0x000000016b7ed4a0 IP 0x00000001067c8b40 size=80    jdk.internal.misc.Signal.findSignal0(Signal.java:65)
  A  SP 0x000000016b7ed4a0 IP 0x00000001067c8b40 size=80    jdk.internal.misc.Signal.(Signal.java:145)
  A  SP 0x000000016b7ed4f0 IP 0x00000001067c8a94 size=64    com.oracle.svm.core.code.FactoryMethodHolder.Signal_5TUKMCDf3wAygDyOPX6zt2(FactoryMethodHolder.java:0)
  A  SP 0x000000016b7ed530 IP 0x000000010630da54 size=48    java.lang.Terminator.setup(Terminator.java:59)
  A  SP 0x000000016b7ed560 IP 0x0000000104d6a694 size=48    com.oracle.svm.core.SubstrateExitHandlerStartupHook.execute(SubstrateExitHandlerFeature.java:47)
  A  SP 0x000000016b7ed590 IP 0x0000000104dc68ec size=64    com.oracle.svm.core.jdk.RuntimeSupport.executeHooks(RuntimeSupport.java:169)
  A  SP 0x000000016b7ed5d0 IP 0x0000000104dc638c size=48    com.oracle.svm.core.jdk.RuntimeSupport.initialize(RuntimeSupport.java:100)
  i  SP 0x000000016b7ed600 IP 0x0000000104d64e78 size=48    org.graalvm.nativeimage.VMRuntime.initialize(VMRuntime.java:65)
  A  SP 0x000000016b7ed600 IP 0x0000000104d64e78 size=48    com.oracle.svm.core.JavaMainWrapper.runCore0(JavaMainWrapper.java:216)
  i  SP 0x000000016b7ed630 IP 0x0000000104d64ce4 size=64    com.oracle.svm.core.JavaMainWrapper.runCore(JavaMainWrapper.java:201)
  A  SP 0x000000016b7ed630 IP 0x0000000104d64ce4 size=64    com.oracle.svm.core.JavaMainWrapper.doRun(JavaMainWrapper.java:299)
  i  SP 0x000000016b7ed670 IP 0x0000000104d862ac size=272   com.oracle.svm.core.JavaMainWrapper.run(JavaMainWrapper.java:284)
  A  SP 0x000000016b7ed670 IP 0x0000000104d862ac size=272   com.oracle.svm.core.code.IsolateEnterStub.JavaMainWrapper_run_XNhh1mz2Ib2aPR1wdv014D(IsolateEnterStub.java:0)

Threads:
  0x0000000134904080 STATUS_IN_NATIVE (ALLOW_SAFEPOINT) "Reference Handler" - 0x00000003021e81d8, daemon, stack(0x000000016b7f4000,0x000000016b877000)
  0x0000000134a04fc0 STATUS_IN_JAVA (PREVENT_VM_FROM_REACHING_SAFEPOINT) "main" - 0x00000003021e8340, stack(0x000000016aff4000,0x000000016b7f0000)

No VMOperation in progress

The 30 most recent VM operation status changes:

VM mutexes:
  mutex "RealLog.backTracePrinterMutex" is unlocked.
  mutex "freeList" is unlocked.
  mutex "mainVMOperationControlWorkQueue" is unlocked.
  mutex "referencePendingList" is unlocked.
  mutex "thread" is unlocked.

Build time information:
  Version: 23+37, serial gc, compressed references
  Platform: darwin/aarch64
  Page size: 65536
  Container support: true
  CPU features used for AOT compiled code: FP, ASIMD

Runtime information:
  CPU cores (container): unknown
  CPU cores (OS): 12
  Memory: 98304M
  Page size: 16384
  VM uptime: 0.006s
  Current timestamp: 1729731380147
  AOT compiled code: 0x0000000104614000 - 0x00000001075a673f

Command line: '--help' 

Heap settings and statistics:
  Supports isolates: true
  Heap base: 0x0000000300000000
  Object reference size: 4
  Reserved object header bits: 0b11111
  Aligned chunk size: 524288
  Large array threshold: 131072
  Incremental collections: 0
  Complete collections: 0

Heap usage:
  Eden: 1.00M (0.00M in 0 aligned chunks, 0.00M in 0 unaligned chunks)
  Old: 0.00M (0.00M in 0 aligned chunks, 0.00M in 0 unaligned chunks)

Native image heap boundaries:
  ReadOnly: 0x0000000300080830 - 0x0000000301878fc8
  ReadOnly Relocatables: 0x0000000301878fc8 - 0x0000000301fcd980
  Writable: 0x0000000301fcd980 - 0x0000000302a5b4e8
  Writable Huge: 0x0000000302a80038 - 0x0000000302d73740
  ReadOnly Huge: 0x0000000302d73778 - 0x0000000304cb85e8

Heap chunks: E=eden, S=survivor, O=old, F=free; A=aligned chunk, U=unaligned chunk; T=to space

Fatal error: Util_jdk_internal_misc_Signal.ensureInitialized: CSunMiscSignal.open() failed.
sgammon commented 1 hour ago

@oubidar-Abderrahim After re-creating the above, I haven't been able to reproduce this issue. Our stacktrace shows a clear source of the error within signal handling code, I can provide that if helpful