Search code examples
javalinuxmongodbjnamongodb-java

java.lang.UnsatisfiedLinkError when /tmp mounted as noexec while using Mongo CSFLE (mongodb-crypt)


I have been working on MongoDB CSFLE (Client-Side Field-Level Encryption) for which there is a dependency in my spring boot project mongodb-crypt-1.0.1. For security reasons, the /tmp partition is mounted as noexec on Ubuntu 16.04 OS running on an EC2. The application startup fails with the following stack trace:

Caused by: java.lang.UnsatisfiedLinkError: /tmp/jna--851256601/jna10844749069600633969.tmp: /tmp/jna--851256601/jna10844749069600633969.tmp: failed to map segment from shared object
    at java.lang.ClassLoader$NativeLibrary.load0(Native Method) ~[?:?]
    at java.lang.ClassLoader$NativeLibrary.load(ClassLoader.java:2430) ~[?:?]
    at java.lang.ClassLoader$NativeLibrary.loadLibrary(ClassLoader.java:2487) ~[?:?]
    at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:2684) ~[?:?]
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:2617) ~[?:?]
    at java.lang.Runtime.load0(Runtime.java:767) ~[?:?]
    at java.lang.System.load(System.java:1834) ~[?:?]
    at com.sun.jna.Native.loadNativeDispatchLibraryFromClasspath(Native.java:947) ~[jna-4.5.2.jar!/:4.5.2 (b0)]
    at com.sun.jna.Native.loadNativeDispatchLibrary(Native.java:922) ~[jna-4.5.2.jar!/:4.5.2 (b0)]
    at com.sun.jna.Native.<clinit>(Native.java:190) ~[jna-4.5.2.jar!/:4.5.2 (b0)]
    at com.mongodb.crypt.capi.CAPI.<clinit>(CAPI.java:778) ~[mongodb-crypt-1.0.1.jar!/:?]
    at com.mongodb.crypt.capi.MongoCryptImpl.<init>(MongoCryptImpl.java:92) ~[mongodb-crypt-1.0.1.jar!/:?]
    at com.mongodb.crypt.capi.MongoCrypts.create(MongoCrypts.java:36) ~[mongodb-crypt-1.0.1.jar!/:?]
    at com.mongodb.client.internal.Crypts.createCrypt(Crypts.java:35) ~[mongo-java-driver-3.12.3.jar!/:?]
...

The application starts up just fine when the /tmp is mounted as exec instead.

Is there any way to solve this without making /tmp executable?


Solution

  • As far as I can tell the crypto parts use JNA and in particular use it to extract libmongocrypt.so into a temporary directory by default. The relevant documentation I believe is https://github.com/java-native-access/jna/blob/master/www/GettingStarted.md.

    I suggest trying:

    1. Setting jna.library.path to a path that is on a filesystem with execution allowed (and copying libmongocrypt.so manually there?).
    2. If this doesn't work, try downloading libmongocrypt.so manually and placing it into a path that your OS can load libraries from without configuration. The download instructions should be the same as for Ruby driver which are here, use the nocrypto version of libmongocrypt.

    Edit: jna.tmpdir seems more appropriate per the comment.