Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mac m1 + code signing == failure #257

Closed
zhuker opened this issue Aug 4, 2021 · 27 comments · Fixed by jnr/jffi#116
Closed

mac m1 + code signing == failure #257

zhuker opened this issue Aug 4, 2021 · 27 comments · Fixed by jnr/jffi#116
Milestone

Comments

@zhuker
Copy link

zhuker commented Aug 4, 2021

running on m1
Darwin vgm1mini.lan 20.6.0 Darwin Kernel Version 20.6.0: Wed Jun 23 00:26:27 PDT 2021; root:xnu-7195.141.2~5/RELEASE_ARM64_T8101 arm64

jnr-ffi version 2.2.3
jvm: azul 8 for aarch64

% java -version
openjdk version "1.8.0_302"
OpenJDK Runtime Environment (Zulu 8.56.0.23-CA-macos-aarch64) (build 1.8.0_302-b08)
OpenJDK 64-Bit Server VM (Zulu 8.56.0.23-CA-macos-aarch64) (build 25.302-b08, mixed mode)

I hear it's a macos feature, is there a workaround you know?

I get this exception

Caused by: java.lang.UnsatisfiedLinkError: could not get native definition for type `POINTER`, original error message follows: java.lang.UnsatisfiedLinkError: Unable to execute or load jffi binary stub from `/var/folders/yn/3fp_cx5s4jj9ws_jk1bb21l40000gn/T/`. Set `TMPDIR` or Java property `java.io.tmpdir` to a read/write path that is not mounted "noexec".
/Users/zhukov/git/vg-brain/bigfoot/jffi7188996843682130746.dylib: dlopen(/Users/zhukov/git/vg-brain/bigfoot/jffi7188996843682130746.dylib, 1): no suitable image found.  Did find:
	/Users/zhukov/git/vg-brain/bigfoot/jffi7188996843682130746.dylib: code signature in (/Users/zhukov/git/vg-brain/bigfoot/jffi7188996843682130746.dylib) not valid for use in process using Library Validation: Trying to load an unsigned library
	at com.kenai.jffi.internal.StubLoader.tempLoadError(StubLoader.java:547)
	at com.kenai.jffi.internal.StubLoader.loadFromJar(StubLoader.java:446)
	at com.kenai.jffi.internal.StubLoader.load(StubLoader.java:321)
	at com.kenai.jffi.internal.StubLoader.<clinit>(StubLoader.java:610)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:348)
	at com.kenai.jffi.Init.load(Init.java:68)
	at com.kenai.jffi.Foreign$InstanceHolder.getInstanceHolder(Foreign.java:50)
	at com.kenai.jffi.Foreign$InstanceHolder.<clinit>(Foreign.java:46)
	at com.kenai.jffi.Foreign.getInstance(Foreign.java:104)
	at com.kenai.jffi.Type$Builtin.lookupTypeInfo(Type.java:242)
	at com.kenai.jffi.Type$Builtin.getTypeInfo(Type.java:237)
	at com.kenai.jffi.Type.resolveSize(Type.java:155)
	at com.kenai.jffi.Type.size(Type.java:138)
	at jnr.ffi.provider.jffi.NativeRuntime$TypeDelegate.size(NativeRuntime.java:182)
	at jnr.ffi.provider.AbstractRuntime.<init>(AbstractRuntime.java:48)
	at jnr.ffi.provider.jffi.NativeRuntime.<init>(NativeRuntime.java:61)
	at jnr.ffi.provider.jffi.NativeRuntime.<init>(NativeRuntime.java:45)
	at jnr.ffi.provider.jffi.NativeRuntime$SingletonHolder.<clinit>(NativeRuntime.java:57)
	at jnr.ffi.provider.jffi.NativeRuntime.getInstance(NativeRuntime.java:53)
	at jnr.ffi.provider.jffi.Provider.<init>(Provider.java:29)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at java.lang.Class.newInstance(Class.java:442)
	at jnr.ffi.provider.FFIProvider$SystemProviderSingletonHolder.getInstance(FFIProvider.java:68)
	at jnr.ffi.provider.FFIProvider$SystemProviderSingletonHolder.<clinit>(FFIProvider.java:57)
	at jnr.ffi.provider.FFIProvider.getSystemProvider(FFIProvider.java:35)
	at jnr.ffi.LibraryLoader.create(LibraryLoader.java:89)
@zhuker
Copy link
Author

zhuker commented Aug 4, 2021

running the below commands does not help

sudo spctl --master-disable
sudo defaults write /Library/Preferences/com.apple.security.libraryvalidation.plist DisableLibraryValidation -bool true

taken from here
https://www.naut.ca/blog/2020/11/13/forbidden-commands-to-liberate-macos/

@headius
Copy link
Member

headius commented Aug 5, 2021

Aha, so we need to do more to sign the binary, somehow.

@zhuker
Copy link
Author

zhuker commented Aug 5, 2021

@headius how can I help?

@headius
Copy link
Member

headius commented Aug 6, 2021

I have not looked into what is required to sign anything... maybe you could poke around on that and slap some links on here?

@zhuker
Copy link
Author

zhuker commented Aug 6, 2021 via email

@lmyslinski
Copy link

Got the same issue:

Caused by: java.lang.UnsatisfiedLinkError: could not get native definition for type `POINTER`, original error message follows: java.lang.UnsatisfiedLinkError: Unable to execute or load jffi binary stub from `/var/folders/fz/jp0r6_1j6n726tjq1hb4qsg40000gn/T/`. Set `TMPDIR` or Java property `java.io.tmpdir` to a read/write path that is not mounted "noexec".

Is there some way to work around this? I've tried running with -Djava.io.tmpdir="/xyz" but didn't help sadly

@headius
Copy link
Member

headius commented Aug 12, 2021

I have an M1 Mac Mini arriving today and will be able to investigate this mor. @zhuker Any luck figuring out what jocl is doing to sign their binaries?

@zhuker
Copy link
Author

zhuker commented Aug 13, 2021

@headius couldnt find any references for code signing in jocl code so created this issue/question gpu/JOCL#41

@charleskorn
Copy link
Contributor

If it helps, I've had reports from a user of a project I maintain with the same issue when running on a M1 Mac: batect/batect#963 (reply in thread).

@rykov
Copy link

rykov commented Sep 8, 2021

I am trying to address this error to run jRuby on M1, and it looks like macOS requires all native code on aarch64 to be signed (introduced in Big Sur). The solutions would be to sign the .jnilib file with a valid Apple Developer ID at build time, or ad-hoc sign the file after it has been extracted, but before it's loaded in StubLoader.loadFromJar.

Here is some basic info for signing a dylib:
https://stackoverflow.com/questions/61168329/how-can-i-sign-a-dylib-using-just-a-normal-apple-id-account-no-developer-accou

As a workaround, I was able to ad-hoc-sign the library to fix this error in my local jRuby:

$ cd $JRUBY_HOME/lib
$ jar xf jruby.jar jni/Darwin/libjffi-1.2.jnilib
$ codesign -s - ./jni/Darwin/libjffi-1.2.jnilib 
$ jar uf jruby.jar jni/Darwin/libjffi-1.2.jnilib

Edit: I'm having trouble with the native library not having correct behavior (jruby/jruby#6813), so even if this workaround fixes the load error, I suggest running jRuby with -Xnative.enabled=false option.

@charleskorn
Copy link
Contributor

I have an M1 Mac Mini arriving today and will be able to investigate this mor.

@headius any luck with this? It'd be great to get a fix into the library. (I'd offer to help myself, but I'm not yet lucky enough to have a M1 Mac)

@pepijnve
Copy link
Contributor

pepijnve commented Nov 5, 2021

@headius I signed the dylib locally with an ad hoc identity (codesign -s - libffi-1.2.jnilib) which is sufficient to get things running locally, but that doesn't help anyone else. Ideally the dylib is signed using one of the core maintainers' Apple developer identity (if anyone has one). See man codesign on your Mac for more details.

@charleskorn
Copy link
Contributor

Based on reports from users of a project I maintain (source), there are two things required for this to work:

  • a recent(ish) JVM - JDK 8 doesn't seem to work, but OpenJDK 16+ works
  • libffi-1.2.jnilib needs to be signed with any signature, including an ad-hoc one - and this can be done once for all users as part of the build process, it doesn't have to be done on a per-machine basis

The steps to sign the .jnilib are those that @rykov posted earlier.

@charleskorn
Copy link
Contributor

charleskorn commented Nov 17, 2021

I've raised jnr/jffi#116 which should fix this issue.

charleskorn added a commit to batect/batect that referenced this issue Nov 21, 2021
…e Silicon machines.

This can be reverted once jnr/jnr-ffi#257 is
resolved (likely with jnr/jffi#116).

See #963.
@headius
Copy link
Member

headius commented Nov 22, 2021

This is a JFFI issue but we'll leave this one targeted at next jnr-ffi which will pull in @charleskorn fix in jnr/jffi#116.

@headius headius added this to the 2.2.9 milestone Nov 22, 2021
@pepijnve
Copy link
Contributor

@headius this issue may need to be reopened. I tried using jnr-ffi:2.2.9/jffi:1.3.7 and still got the code signing error. I extracted the Darwin jnilib file from the jar and checked the signature of the file. Doesn't seem to be signed:

pepijn@Kerel ~ % codesign -d libjffi-1.2.jnilib 
libjffi-1.2.jnilib: code object is not signed at all

@headius
Copy link
Member

headius commented Nov 23, 2021

Oh shoot... perhaps I needed to rebuild on Darwin to get the signature?

@pepijnve Could you give that a try and see if the resulting binary works better? I did not even think to check if the PR provided a new binary, but it makes sense that it would not (i.e. it's my job to sign and ship it).

@headius headius reopened this Nov 23, 2021
@headius headius modified the milestones: 2.2.9, 2.2.10 Nov 23, 2021
@pepijnve
Copy link
Contributor

The PR only modifies the build script on Darwin with the command to do as hoc signing of the library. A rebuild is required indeed. The command that's added by the patch is what I did locally to get things working, so that should do the trick. I can test this locally tomorrow to make sure that extracting from the jar with a unique name doesn't break anything. Local testing so far was with an already extracted binary and setting the boot path.

@pepijnve
Copy link
Contributor

@headius I replaced libjffi-1.2.jnlib in my local copy of the jar file with a version that I manually signed with codesign -s - ... and then retested my own code. Works as desired then so a rebuild should be all that's required.

@headius
Copy link
Member

headius commented Nov 26, 2021

Okay, I'll do a local rebuild soon and get a release out early next week. If I can figure out how to sign it with my own certificate that would be even better.

@headius
Copy link
Member

headius commented Dec 1, 2021

I have released jffi 1.3.8 with the rebuilt and signed binary. Please confirm?

@pepijnve
Copy link
Contributor

pepijnve commented Dec 1, 2021

I'll give this a try asap.

@pepijnve
Copy link
Contributor

pepijnve commented Dec 1, 2021

I can already provide you some details on how to do signing with a real certificate in the meantime. You'll need to create a 'Developer ID application' type certificate at developer.apple.com

Screenshot 2021-12-01 at 14 15 49

Fire up Xcode and it should show up there as well once it has been created

Screenshot 2021-12-01 at 14 16 38

I'm not sure how to do this part in a non-interactive environment I'm afraid. The signing identities are sourced from your keychains, so maybe it's sufficient to download the certificate bits from developer.apple.com and insert them into a keychain using security import.

You can list the available signing identities using security find-identity -v -p codesigning.

  1) <redacted> "Apple Development: Pepijn Van Eeckhoudt (<redacted>)"
  2) <redacted> "Developer ID Application: Pepijn Van Eeckhoudt (<redacted>)"
     2 valid identities found

Finally you can then sign using the identity label from the output above as value for -s instead of -.

@headius
Copy link
Member

headius commented Dec 1, 2021

Yeah I started looking at the docs for properly signing. I will check if my Apple Dev ID is still valid and we can try to get the patches in place to sign for reals.

@pepijnve
Copy link
Contributor

pepijnve commented Dec 1, 2021

Tested with my local libcrypto binding. Works perfectly out of the box on an m1, both with an aarch64 and an x86_64 JVM. Tested with Azul JDK 11 builds.

@headius
Copy link
Member

headius commented Dec 1, 2021

@pepijnve Thank you for your confirmation and patience!

I am spinning releases of the rest of the JNR stack so that versions align properly.

@headius
Copy link
Member

headius commented Dec 1, 2021

I have released the rest of the stack (and updated JRuby HEADs to use them).

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 a pull request may close this issue.

6 participants