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

jffi9396993929588479283.so: /lib64/libc.so.6: version `GLIBC_2.27' not found #138

Closed
kingluo opened this issue Nov 22, 2022 · 55 comments · Fixed by jnr/jnr-ffi#326 or #155 · May be fixed by #153
Closed

jffi9396993929588479283.so: /lib64/libc.so.6: version `GLIBC_2.27' not found #138

kingluo opened this issue Nov 22, 2022 · 55 comments · Fixed by jnr/jnr-ffi#326 or #155 · May be fixed by #153
Milestone

Comments

@kingluo
Copy link

kingluo commented Nov 22, 2022

The error message is very weird.

In Centos7 with openjdk 11:

...
Exception in thread "Thread-0" java.lang.UnsatisfiedLinkError: could not load FFI provider jnr.ffi.provider.jffi.Provider
        at jnr.ffi.provider.InvalidRuntime.newLoadError(InvalidRuntime.java:102)
        at jnr.ffi.provider.InvalidRuntime.getMemoryManager(InvalidRuntime.java:53)
        at jnr.ffi.Pointer.wrap(Pointer.java:48)
        at demo.echo.PollThread.run(App.java:30)
        at java.base/java.lang.Thread.run(Thread.java:829)
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 `/home/`. Set `TMPDIR` or Java property `java.io.tmpdir` to a read/write path that is not mounted "noexec".
.../jffi9396993929588479283.so: /lib64/libc.so.6: version `GLIBC_2.27' not found (required by .../jffi9396993929588479
283.so)
        at com.kenai.jffi.internal.StubLoader.tempLoadError(StubLoader.java:555)
...

It reports noexec problem, but the /home is not mounted with noexec, is it symbol issue?
I found only memfd_create C symbol comes from `GLIBC_2.27'.

Please help, thanks.

@Sobakaa
Copy link

Sobakaa commented Dec 28, 2022

Faced the same issue recently. Still investigating, not sure yet if it's tied to a java update or centos update on our side, as it used to work about a month ago.

@Sobakaa
Copy link

Sobakaa commented Dec 28, 2022

Not an issue on our end, it seems. Once i downgraded to jnr 2.1.12 the problem disappeared. Sadly will have to exclude this library from auto-updates for the time being.

@DManstrator
Copy link

I am also facing this exact issue.

Failed to execute goal io.fabric8:docker-maven-plugin:0.41.0:build (default) on project my-project: Execution default of goal io.fabric8:docker-maven-plugin:0.41.0:build failed: An API incompatibility was encountered while executing io.fabric8:docker-maven-plugin:0.41.0:build: java.lang.UnsatisfiedLinkError: could not load FFI provider jnr.ffi.provider.jffi.Provider
[...]
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 `/tmp/foobar`. Set `TMPDIR` or Java property `java.io.tmpdir` to a read/write path that is not mounted "noexec".
/appl/bamboo-agent/xml-data/build-dir/[...]/jffi16914516266569452708.so: /lib64/libc.so.6: version `GLIBC_2.27' not found (required by /appl/bamboo-agent/xml-data/build-dir/[...]/jffi16914516266569452708.so)

The latest docker-maven-plugin update (v0.41.0) updated JNR UnixSocket to v0.38.19. This however updated JNR-FFI from 2.1.11 to 2.1.13.

Since then my bamboo builds are failing. When going back to docker-maven-plugin v0.40.3, the builds are running through again.

@RainerGanss
Copy link

We have the same error which is prevent us to upgrade to the newest version.

@headius
Copy link
Member

headius commented Feb 16, 2023

Looking into this now. Anyone have any idea what version this started at?

Over the past year we've moved to using GHA to do builds of all the Linux-based jffi binaries. When building for x86_64, I believe we just build directly on GHA, so it's going to be a very recent version of Ubuntu/Debian-ish Linux. If we need to be mindful of the glibc version, that will require some finesse.

@headius
Copy link
Member

headius commented Feb 16, 2023

This however updated JNR-FFI from 2.1.11 to 2.1.13.

@DManstrator So that narrows it down, thank you.

@headius
Copy link
Member

headius commented Feb 16, 2023

FWIW this is really a jffi issue so I'm going to move it there.

@headius headius transferred this issue from jnr/jnr-ffi Feb 16, 2023
@headius
Copy link
Member

headius commented Feb 16, 2023

Ok so we are also building x86_64 binaries using Docker, so there's a path to use an older Linux install that has an earlier glibc version.

Unfortunately, we're building based on Debian, and even as far back as debian:8, the closest we get is glibc 2.19.

The alternative to this would be having the build fetch and build an older glibc and link against that, but that's quite a bit more work.

I will try a branch that uses debian:8 to build and see if it works for those of you on CentOS 7.

@headius
Copy link
Member

headius commented Feb 16, 2023

Anyone having this issue that's NOT on CentOS 7?

headius added a commit that referenced this issue Feb 16, 2023
Building on debian:10 results in a binary that requires glibc 2.27
which is not available on some LTS server Linuxes like CentOS 7.
This commit attempts to make a compatible jffi.so using debian:8,
which ships with glibc 2.19. This is not as old as 2.17 but may
remove enough dependencies on newer glibc to be sufficient.

See #138
@headius
Copy link
Member

headius commented Feb 16, 2023

Ok, there it is... can someone on CentOS 7 give the binaries here a try?

https://github.com/jnr/jffi/actions/runs/4196057988

Everything seems to have built ok on debian:8. We can try to go even earlier, but we're getting into weird territory.

@headius
Copy link
Member

headius commented Feb 28, 2023

My PR in #138 did not work unfortunately. Switching to debian:8 did not appear to produce binaries for older glibc.

I welcome assistance getting this to build with older glibc in CI.

@kingluo
Copy link
Author

kingluo commented Mar 1, 2023

Let me clarify a bit more.

Debian >= 9 and ubuntu >= 20.04 have no problem.

This issue is only on CentOS7. Besides the symbol issue, it looks like a directory permission bug.

Here is the full logs:

Exception in thread "Thread-0" java.lang.UnsatisfiedLinkError: could not load FFI provider jnr.ffi.provider.jffi.Provider
        at jnr.ffi.provider.InvalidRuntime.newLoadError(InvalidRuntime.java:102)
        at jnr.ffi.provider.InvalidRuntime.getMemoryManager(InvalidRuntime.java:53)
        at jnr.ffi.Pointer.wrap(Pointer.java:48)
        at demo.echo.PollThread.run(App.java:30)
        at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.lang.UnsatisfiedLinkError: could not get native definition for type `POINTER`, original error message follows: java.io.IOException: Unable to write jffi
 binary stub to `/tmp`. Set `TMPDIR` or Java property `java.io.tmpdir` to a read/write path that is not mounted "noexec".
        at com.kenai.jffi.internal.StubLoader.tempReadonlyError(StubLoader.java:545)
        at com.kenai.jffi.internal.StubLoader.loadFromJar(StubLoader.java:446)
        at com.kenai.jffi.internal.StubLoader.load(StubLoader.java:330)
        at com.kenai.jffi.internal.StubLoader.<clinit>(StubLoader.java:618)
        at java.base/java.lang.Class.forName0(Native Method)
        at java.base/java.lang.Class.forName(Class.java:398)
        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:198)
        at jnr.ffi.provider.AbstractRuntime.<init>(AbstractRuntime.java:48)
        at jnr.ffi.provider.jffi.NativeRuntime.<init>(NativeRuntime.java:77)
        at jnr.ffi.provider.jffi.NativeRuntime.<init>(NativeRuntime.java:49)
        at jnr.ffi.provider.jffi.NativeRuntime$SingletonHolder.<clinit>(NativeRuntime.java:73)
        at jnr.ffi.provider.jffi.NativeRuntime.getInstance(NativeRuntime.java:60)
        at jnr.ffi.provider.jffi.Provider.<init>(Provider.java:29)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
        at java.base/java.lang.Class.newInstance(Class.java:584)
        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)
        at demo.echo.PollThread.run(App.java:28)
        at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.io.IOException: Permission denied
        at java.base/java.io.UnixFileSystem.createFileExclusively(Native Method)
        at java.base/java.io.File.createTempFile(File.java:2129)
        at com.kenai.jffi.internal.StubLoader.calculateExtractPath(StubLoader.java:536)
        at com.kenai.jffi.internal.StubLoader.calculateExtractPath(StubLoader.java:505)
        at com.kenai.jffi.internal.StubLoader.loadFromJar(StubLoader.java:437)
        ... 30 more

        at com.kenai.jffi.Type$Builtin.lookupTypeInfo(Type.java:253)
        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:198)
        at jnr.ffi.provider.AbstractRuntime.<init>(AbstractRuntime.java:48)
        at jnr.ffi.provider.jffi.NativeRuntime.<init>(NativeRuntime.java:77)
        at jnr.ffi.provider.jffi.NativeRuntime.<init>(NativeRuntime.java:49)
        at jnr.ffi.provider.jffi.NativeRuntime$SingletonHolder.<clinit>(NativeRuntime.java:73)
        at jnr.ffi.provider.jffi.NativeRuntime.getInstance(NativeRuntime.java:60)
        at jnr.ffi.provider.jffi.Provider.<init>(Provider.java:29)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
        at java.base/java.lang.Class.newInstance(Class.java:584)
        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)
        at demo.echo.PollThread.run(App.java:28)
        ... 1 more

@headius
Copy link
Member

headius commented Mar 1, 2023

@kingluo That looks more like an SELinux restriction, preventing the usual temp directories from being used for executable code. You would either disable SELinux or set a temp dir that does not have such restrictions (like one that is local to the current user).

The main challenge at the moment is that I don't know how to build the Linux jffi extension against an old glibc using Github Actions. We have a rig that uses Docker and qemu to build for a number of different Linux platforms, but setting that to debian:8 (the earliest image available) did not roll back glibc far enough.

@kingluo
Copy link
Author

kingluo commented Mar 1, 2023

@headius

You would either disable SELinux or set a temp dir that does not have such restrictions (like one that is local to the current user).

I tried both before, but it does not work. It seems a false log.

The main challenge at the moment is that I don't know how to build the Linux jffi extension against an old glibc using Github Actions.

I am curious about that did you try to build it in the local environment (VM or container) with Debian8 or Centos7 and test it without a problem? If so, then GitHub action is an insignificant side issue.

@headius
Copy link
Member

headius commented Mar 1, 2023

@kingluo Ok, maybe open that as a separate bug.

@headius
Copy link
Member

headius commented Mar 1, 2023

@kingluo ...

GitHub action is an insignificant side issue

I need for anyone to be able to reproduce these builds in any environment, and making it happen in GHA is an easy way to do that (just reproduce the docker setup and it will work).

I can certainly build it myself in my CentOS7 VM, but then I'll have to manually do that again next time, and the following times, etc.

If this is a serious blocker for folks on this issue, we could go with the CentOS 7 manual build for one release, but I need to automate it somehow.

@kingluo
Copy link
Author

kingluo commented Mar 2, 2023

@headius Have you reproduced the bug and found a bug fix?

@mabrarov
Copy link

mabrarov commented Mar 2, 2023

Hi,

In case of CentOS 7 and RHEL 7 this issue seems to be caused by mismatch of Glibc version. I have the following stack trace from Jenkins (running on RHEL 7):

[ERROR] -----------------------------------------------------: could not get native definition for type `POINTER`, original error message follows: java.lang.UnsatisfiedLinkError: Unable to execute or load jffi binary stub from `/tmp`. Set `TMPDIR` or Java property `java.io.tmpdir` to a read/write path that is not mounted "noexec".
[ERROR] /scm/Checkout/DIM/SSS/pullrequest/jffi14641814068934548873.so: /lib64/libc.so.6: version `GLIBC_2.27' not found (required by /scm/Checkout/DIM/SSS/pullrequest/jffi14641814068934548873.so)
[ERROR] 	at com.kenai.jffi.internal.StubLoader.tempLoadError(StubLoader.java:555)
[ERROR] 	at com.kenai.jffi.internal.StubLoader.loadFromJar(StubLoader.java:454)
[ERROR] 	at com.kenai.jffi.internal.StubLoader.load(StubLoader.java:330)
[ERROR] 	at com.kenai.jffi.internal.StubLoader.<clinit>(StubLoader.java:618)
[ERROR] 	at java.base/java.lang.Class.forName0(Native Method)
[ERROR] 	at java.base/java.lang.Class.forName(Class.java:467)
[ERROR] 	at com.kenai.jffi.Init.load(Init.java:68)
[ERROR] 	at com.kenai.jffi.Foreign$InstanceHolder.getInstanceHolder(Foreign.java:50)
[ERROR] 	at com.kenai.jffi.Foreign$InstanceHolder.<clinit>(Foreign.java:46)
[ERROR] 	at com.kenai.jffi.Foreign.getInstance(Foreign.java:104)
[ERROR] 	at com.kenai.jffi.Type$Builtin.lookupTypeInfo(Type.java:242)
[ERROR] 	at com.kenai.jffi.Type$Builtin.getTypeInfo(Type.java:237)
[ERROR] 	at com.kenai.jffi.Type.resolveSize(Type.java:155)
[ERROR] 	at com.kenai.jffi.Type.size(Type.java:138)
[ERROR] 	at jnr.ffi.provider.jffi.NativeRuntime$TypeDelegate.size(NativeRuntime.java:198)
[ERROR] 	at jnr.ffi.provider.AbstractRuntime.<init>(AbstractRuntime.java:48)
[ERROR] 	at jnr.ffi.provider.jffi.NativeRuntime.<init>(NativeRuntime.java:77)
[ERROR] 	at jnr.ffi.provider.jffi.NativeRuntime.<init>(NativeRuntime.java:49)
[ERROR] 	at jnr.ffi.provider.jffi.NativeRuntime$SingletonHolder.<clinit>(NativeRuntime.java:73)
[ERROR] 	at jnr.ffi.provider.jffi.NativeRuntime.getInstance(NativeRuntime.java:60)
[ERROR] 	at jnr.ffi.provider.jffi.Provider.<init>(Provider.java:29)
[ERROR] 	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
[ERROR] 	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
[ERROR] 	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
[ERROR] 	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
[ERROR] 	at java.base/java.lang.reflect.ReflectAccess.newInstance(ReflectAccess.java:128)
[ERROR] 	at java.base/jdk.internal.reflect.ReflectionFactory.newInstance(ReflectionFactory.java:347)
[ERROR] 	at java.base/java.lang.Class.newInstance(Class.java:645)
[ERROR] 	at jnr.ffi.provider.FFIProvider$SystemProviderSingletonHolder.getInstance(FFIProvider.java:68)
[ERROR] 	at jnr.ffi.provider.FFIProvider$SystemProviderSingletonHolder.<clinit>(FFIProvider.java:57)
[ERROR] 	at jnr.ffi.provider.FFIProvider.getSystemProvider(FFIProvider.java:35)
[ERROR] 	at jnr.ffi.LibraryLoader.create(LibraryLoader.java:89)
[ERROR] 	at jnr.unixsocket.Native.<clinit>(Native.java:76)
[ERROR] 	at jnr.unixsocket.UnixSocketChannel.<init>(UnixSocketChannel.java:101)
[ERROR] 	at jnr.unixsocket.UnixSocketChannel.open(UnixSocketChannel.java:60)
[ERROR] 	at io.fabric8.maven.docker.access.util.LocalSocketUtil.canConnectUnixSocket(LocalSocketUtil.java:38)
[ERROR] 	at io.fabric8.maven.docker.access.DockerConnectionDetector$UnixSocketDockerHostProvider.getConnectionParameter(DockerConnectionDetector.java:113)
[ERROR] 	at io.fabric8.maven.docker.access.DockerConnectionDetector.detectConnectionParameter(DockerConnectionDetector.java:82)
[ERROR] 	at io.fabric8.maven.docker.service.DockerAccessFactory.createDockerAccess(DockerAccessFactory.java:34)
[ERROR] 	at io.fabric8.maven.docker.AbstractDockerMojo.execute(AbstractDockerMojo.java:274)
[ERROR] 	at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:137)
[ERROR] 	at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:210)
[ERROR] 	at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:156)
[ERROR] 	at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:148)
[ERROR] 	at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)
[ERROR] 	at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
[ERROR] 	at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:56)
[ERROR] 	at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
[ERROR] 	at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:305)
[ERROR] 	at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:192)
[ERROR] 	at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:105)
[ERROR] 	at org.apache.maven.cli.MavenCli.execute(MavenCli.java:957)
[ERROR] 	at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:289)
[ERROR] 	at org.apache.maven.cli.MavenCli.main(MavenCli.java:193)
[ERROR] 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[ERROR] 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
[ERROR] 	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[ERROR] 	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
[ERROR] 	at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:282)
[ERROR] 	at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:225)
[ERROR] 	at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:406)
[ERROR] 	at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:347)

Glibc version on respective Jenkins node is 2.17 (i.e. older than required 2.27):

$ cat /etc/*release    
NAME="Red Hat Enterprise Linux Server"
VERSION="7.9 (Maipo)"
ID="rhel"
ID_LIKE="fedora"
VARIANT="Server"
VARIANT_ID="server"
VERSION_ID="7.9"
PRETTY_NAME="Red Hat Enterprise Linux Server 7.9 (Maipo)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:redhat:enterprise_linux:7.9:GA:server"
HOME_URL="https://www.redhat.com/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"

REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 7"
REDHAT_BUGZILLA_PRODUCT_VERSION=7.9
REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="7.9"
Red Hat Enterprise Linux Server release 7.9 (Maipo)
Red Hat Enterprise Linux Server release 7.9 (Maipo)

$ ldd --version
ldd (GNU libc) 2.17
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.

@headius
Copy link
Member

headius commented Mar 8, 2023

@kingluo I have reproduced it and the only fix I know of at the moment is to build the extension on CentOS7/RHEL7.

headius added a commit that referenced this issue Mar 8, 2023
Building on debian:10 results in a binary that requires glibc 2.27
which is not available on some LTS server Linuxes like CentOS 7.
This commit attempts to make a compatible jffi.so using debian:8,
which ships with glibc 2.19. This is not as old as 2.17 but may
remove enough dependencies on newer glibc to be sufficient.

See #138
@headius
Copy link
Member

headius commented Mar 8, 2023

The new PR #140 appears to build a working binary! I will update it to have the new build archived and available and then need someone to confirm it locally before release.

@headius
Copy link
Member

headius commented Mar 8, 2023

PR #140 now has an updated archived build for Linux x86_64 that appears to work on CentOS 7. Can someone verify that branch works for them?

@mabrarov
Copy link

mabrarov commented Mar 9, 2023

Hi @headius,

I confirm that Linux x86_64 binary from PR #140 fixes this issue. Here is my test I performed on CentOS 7.9:

  1. The system I used:

    $ cat /etc/*release
    CentOS Linux release 7.9.2009 (Core)
    NAME="CentOS Linux"
    VERSION="7 (Core)"
    ID="centos"
    ID_LIKE="rhel fedora"
    VERSION_ID="7"
    PRETTY_NAME="CentOS Linux 7 (Core)"
    ANSI_COLOR="0;31"
    CPE_NAME="cpe:/o:centos:centos:7"
    HOME_URL="https://www.centos.org/"
    BUG_REPORT_URL="https://bugs.centos.org/"
    
    CENTOS_MANTISBT_PROJECT="CentOS-7"
    CENTOS_MANTISBT_PROJECT_VERSION="7"
    REDHAT_SUPPORT_PRODUCT="centos"
    REDHAT_SUPPORT_PRODUCT_VERSION="7"
    
    CentOS Linux release 7.9.2009 (Core)
    CentOS Linux release 7.9.2009 (Core)
    
  2. I use docker-maven-plugin to build docker images with Maven.

  3. When I upgraded docker-maven-plugin till 0.42.0 version (which uses jffi 1.3.10), my build started failing:

    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD FAILURE
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  01:01 min
    [INFO] Finished at: 2023-03-09T03:32:20+03:00
    [INFO] ------------------------------------------------------------------------
    [ERROR] Failed to execute goal io.fabric8:docker-maven-plugin:0.42.0:build (build-docker-image) on project geode-image: Execution build-docker-image of goal io.fabric8:docker-maven-plugin:0.42.0:build failed: An API incompatibility was encountered while executing io.fabric8:docker-maven-plugin:0.42.0:build: java.lang.UnsatisfiedLinkError: could not load FFI provider jnr.ffi.provider.jffi.Provider
    [ERROR] -----------------------------------------------------
    [ERROR] realm =    plugin>io.fabric8:docker-maven-plugin:0.42.0
    [ERROR] strategy = org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy
    [ERROR] urls[0] = file:/repository/io/fabric8/docker-maven-plugin/0.42.0/docker-maven-plugin-0.42.0.jar
    [ERROR] urls[1] = file:/repository/com/github/jnr/jnr-unixsocket/0.38.19/jnr-unixsocket-0.38.19.jar
    [ERROR] urls[2] = file:/repository/com/github/jnr/jnr-ffi/2.2.13/jnr-ffi-2.2.13.jar
    [ERROR] urls[3] = file:/repository/com/github/jnr/jffi/1.3.10/jffi-1.3.10.jar
    [ERROR] urls[4] = file:/repository/com/github/jnr/jffi/1.3.10/jffi-1.3.10-native.jar
    [ERROR] urls[5] = file:/repository/org/ow2/asm/asm-commons/9.2/asm-commons-9.2.jar
    [ERROR] urls[6] = file:/repository/org/ow2/asm/asm-analysis/9.2/asm-analysis-9.2.jar
    [ERROR] urls[7] = file:/repository/org/ow2/asm/asm-tree/9.2/asm-tree-9.2.jar
    [ERROR] urls[8] = file:/repository/org/ow2/asm/asm-util/9.2/asm-util-9.2.jar
    [ERROR] urls[9] = file:/repository/com/github/jnr/jnr-a64asm/1.0.0/jnr-a64asm-1.0.0.jar
    [ERROR] urls[10] = file:/repository/com/github/jnr/jnr-x86asm/1.0.2/jnr-x86asm-1.0.2.jar
    [ERROR] urls[11] = file:/repository/com/github/jnr/jnr-constants/0.10.4/jnr-constants-0.10.4.jar
    [ERROR] urls[12] = file:/repository/com/github/jnr/jnr-enxio/0.32.14/jnr-enxio-0.32.14.jar
    [ERROR] urls[13] = file:/repository/com/github/jnr/jnr-posix/3.1.16/jnr-posix-3.1.16.jar
    [ERROR] urls[14] = file:/repository/com/google/cloud/tools/jib-core/0.23.0/jib-core-0.23.0.jar
    [ERROR] urls[15] = file:/repository/com/google/cloud/tools/jib-build-plan/0.4.0/jib-build-plan-0.4.0.jar
    [ERROR] urls[16] = file:/repository/com/google/http-client/google-http-client/1.42.2/google-http-client-1.42.2.jar
    [ERROR] urls[17] = file:/repository/io/opencensus/opencensus-api/0.31.1/opencensus-api-0.31.1.jar
    [ERROR] urls[18] = file:/repository/io/grpc/grpc-context/1.27.2/grpc-context-1.27.2.jar
    [ERROR] urls[19] = file:/repository/io/opencensus/opencensus-contrib-http-util/0.31.1/opencensus-contrib-http-util-0.31.1.jar
    [ERROR] urls[20] = file:/repository/com/google/http-client/google-http-client-apache-v2/1.42.2/google-http-client-apache-v2-1.42.2.jar
    [ERROR] urls[21] = file:/repository/com/google/auth/google-auth-library-oauth2-http/1.10.0/google-auth-library-oauth2-http-1.10.0.jar
    [ERROR] urls[22] = file:/repository/com/google/auto/value/auto-value-annotations/1.9/auto-value-annotations-1.9.jar
    [ERROR] urls[23] = file:/repository/com/google/auth/google-auth-library-credentials/1.10.0/google-auth-library-credentials-1.10.0.jar
    [ERROR] urls[24] = file:/repository/com/google/http-client/google-http-client-gson/1.42.2/google-http-client-gson-1.42.2.jar
    [ERROR] urls[25] = file:/repository/org/apache/commons/commons-compress/1.21/commons-compress-1.21.jar
    [ERROR] urls[26] = file:/repository/com/fasterxml/jackson/core/jackson-databind/2.13.4.2/jackson-databind-2.13.4.2.jar
    [ERROR] urls[27] = file:/repository/com/fasterxml/jackson/core/jackson-annotations/2.13.4/jackson-annotations-2.13.4.jar
    [ERROR] urls[28] = file:/repository/com/fasterxml/jackson/core/jackson-core/2.13.4/jackson-core-2.13.4.jar
    [ERROR] urls[29] = file:/repository/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.13.4/jackson-datatype-jsr310-2.13.4.jar
    [ERROR] urls[30] = file:/repository/org/ow2/asm/asm/9.4/asm-9.4.jar
    [ERROR] urls[31] = file:/repository/com/google/code/gson/gson/2.8.9/gson-2.8.9.jar
    [ERROR] urls[32] = file:/repository/com/google/guava/guava/31.1-jre/guava-31.1-jre.jar
    [ERROR] urls[33] = file:/repository/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar
    [ERROR] urls[34] = file:/repository/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar
    [ERROR] urls[35] = file:/repository/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar
    [ERROR] urls[36] = file:/repository/org/checkerframework/checker-qual/3.12.0/checker-qual-3.12.0.jar
    [ERROR] urls[37] = file:/repository/com/google/errorprone/error_prone_annotations/2.11.0/error_prone_annotations-2.11.0.jar
    [ERROR] urls[38] = file:/repository/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar
    [ERROR] urls[39] = file:/repository/net/jodah/failsafe/2.4.0/failsafe-2.4.0.jar
    [ERROR] urls[40] = file:/repository/org/apache/commons/commons-lang3/3.6/commons-lang3-3.6.jar
    [ERROR] urls[41] = file:/repository/org/apache/commons/commons-text/1.1/commons-text-1.1.jar
    [ERROR] urls[42] = file:/repository/org/apache/httpcomponents/httpclient/4.5.13/httpclient-4.5.13.jar
    [ERROR] urls[43] = file:/repository/org/apache/httpcomponents/httpcore/4.4.13/httpcore-4.4.13.jar
    [ERROR] urls[44] = file:/repository/commons-logging/commons-logging/1.2/commons-logging-1.2.jar
    [ERROR] urls[45] = file:/repository/commons-codec/commons-codec/1.11/commons-codec-1.11.jar
    [ERROR] urls[46] = file:/repository/org/apache/maven/plugins/maven-assembly-plugin/3.1.0/maven-assembly-plugin-3.1.0.jar
    [ERROR] urls[47] = file:/repository/org/sonatype/sisu/sisu-inject-bean/1.4.2/sisu-inject-bean-1.4.2.jar
    [ERROR] urls[48] = file:/repository/org/sonatype/sisu/sisu-guice/2.1.7/sisu-guice-2.1.7-noaop.jar
    [ERROR] urls[49] = file:/repository/org/sonatype/aether/aether-util/1.7/aether-util-1.7.jar
    [ERROR] urls[50] = file:/repository/org/codehaus/plexus/plexus-component-annotations/1.5.5/plexus-component-annotations-1.5.5.jar
    [ERROR] urls[51] = file:/repository/org/sonatype/plexus/plexus-sec-dispatcher/1.3/plexus-sec-dispatcher-1.3.jar
    [ERROR] urls[52] = file:/repository/org/sonatype/plexus/plexus-cipher/1.4/plexus-cipher-1.4.jar
    [ERROR] urls[53] = file:/repository/org/apache/maven/shared/maven-common-artifact-filters/3.0.1/maven-common-artifact-filters-3.0.1.jar
    [ERROR] urls[54] = file:/repository/org/apache/maven/shared/maven-shared-utils/3.1.0/maven-shared-utils-3.1.0.jar
    [ERROR] urls[55] = file:/repository/org/apache/maven/shared/maven-artifact-transfer/0.9.0/maven-artifact-transfer-0.9.0.jar
    [ERROR] urls[56] = file:/repository/org/codehaus/plexus/plexus-archiver/3.5/plexus-archiver-3.5.jar
    [ERROR] urls[57] = file:/repository/org/iq80/snappy/snappy/0.4/snappy-0.4.jar
    [ERROR] urls[58] = file:/repository/org/tukaani/xz/1.6/xz-1.6.jar
    [ERROR] urls[59] = file:/repository/org/apache/maven/shared/file-management/3.0.0/file-management-3.0.0.jar
    [ERROR] urls[60] = file:/repository/org/apache/maven/shared/maven-shared-io/3.0.0/maven-shared-io-3.0.0.jar
    [ERROR] urls[61] = file:/repository/commons-io/commons-io/2.5/commons-io-2.5.jar
    [ERROR] urls[62] = file:/repository/org/apache/maven/shared/maven-filtering/3.1.1/maven-filtering-3.1.1.jar
    [ERROR] urls[63] = file:/repository/org/sonatype/plexus/plexus-build-api/0.0.7/plexus-build-api-0.0.7.jar
    [ERROR] urls[64] = file:/repository/org/codehaus/plexus/plexus-io/3.0.0/plexus-io-3.0.0.jar
    [ERROR] urls[65] = file:/repository/org/apache/maven/maven-archiver/3.2.0/maven-archiver-3.2.0.jar
    [ERROR] urls[66] = file:/repository/org/codehaus/plexus/plexus-utils/3.1.0/plexus-utils-3.1.0.jar
    [ERROR] urls[67] = file:/repository/org/bouncycastle/bcpkix-jdk15on/1.65/bcpkix-jdk15on-1.65.jar
    [ERROR] urls[68] = file:/repository/org/bouncycastle/bcprov-jdk15on/1.65/bcprov-jdk15on-1.65.jar
    [ERROR] urls[69] = file:/repository/org/codehaus/plexus/plexus-interpolation/1.24/plexus-interpolation-1.24.jar
    [ERROR] urls[70] = file:/repository/org/yaml/snakeyaml/1.32/snakeyaml-1.32.jar
    [ERROR] Number of foreign imports: 1
    [ERROR] import: Entry[import  from realm ClassRealm[maven.api, parent: null]]
    [ERROR]
    [ERROR] -----------------------------------------------------
    [ERROR] : could not get native definition for type `POINTER`, original error message follows: java.lang.UnsatisfiedLinkError: Unable to execute or load jffi binary stub from `/tmp`. Set `TMPDIR` or Java property `java.io.tmpdir` to a read/write path that is not mounted "noexec".
    [ERROR] /ws/dimension/geode-docker/jffi10422774291879544072.so: /lib64/libc.so.6: version `GLIBC_2.27' not found (required by /ws/dimension/geode-docker/jffi10422774291879544072.so)
    [ERROR] 	at com.kenai.jffi.internal.StubLoader.tempLoadError(StubLoader.java:555)
    [ERROR] 	at com.kenai.jffi.internal.StubLoader.loadFromJar(StubLoader.java:454)
    [ERROR] 	at com.kenai.jffi.internal.StubLoader.load(StubLoader.java:330)
    [ERROR] 	at com.kenai.jffi.internal.StubLoader.<clinit>(StubLoader.java:618)
    [ERROR] 	at java.base/java.lang.Class.forName0(Native Method)
    [ERROR] 	at java.base/java.lang.Class.forName(Class.java:467)
    [ERROR] 	at com.kenai.jffi.Init.load(Init.java:68)
    [ERROR] 	at com.kenai.jffi.Foreign$InstanceHolder.getInstanceHolder(Foreign.java:50)
    [ERROR] 	at com.kenai.jffi.Foreign$InstanceHolder.<clinit>(Foreign.java:46)
    [ERROR] 	at com.kenai.jffi.Foreign.getInstance(Foreign.java:104)
    [ERROR] 	at com.kenai.jffi.Type$Builtin.lookupTypeInfo(Type.java:242)
    [ERROR] 	at com.kenai.jffi.Type$Builtin.getTypeInfo(Type.java:237)
    [ERROR] 	at com.kenai.jffi.Type.resolveSize(Type.java:155)
    [ERROR] 	at com.kenai.jffi.Type.size(Type.java:138)
    [ERROR] 	at jnr.ffi.provider.jffi.NativeRuntime$TypeDelegate.size(NativeRuntime.java:198)
    [ERROR] 	at jnr.ffi.provider.AbstractRuntime.<init>(AbstractRuntime.java:48)
    [ERROR] 	at jnr.ffi.provider.jffi.NativeRuntime.<init>(NativeRuntime.java:77)
    [ERROR] 	at jnr.ffi.provider.jffi.NativeRuntime.<init>(NativeRuntime.java:49)
    [ERROR] 	at jnr.ffi.provider.jffi.NativeRuntime$SingletonHolder.<clinit>(NativeRuntime.java:73)
    [ERROR] 	at jnr.ffi.provider.jffi.NativeRuntime.getInstance(NativeRuntime.java:60)
    [ERROR] 	at jnr.ffi.provider.jffi.Provider.<init>(Provider.java:29)
    [ERROR] 	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    [ERROR] 	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
    [ERROR] 	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    [ERROR] 	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
    [ERROR] 	at java.base/java.lang.reflect.ReflectAccess.newInstance(ReflectAccess.java:128)
    [ERROR] 	at java.base/jdk.internal.reflect.ReflectionFactory.newInstance(ReflectionFactory.java:347)
    [ERROR] 	at java.base/java.lang.Class.newInstance(Class.java:645)
    [ERROR] 	at jnr.ffi.provider.FFIProvider$SystemProviderSingletonHolder.getInstance(FFIProvider.java:68)
    [ERROR] 	at jnr.ffi.provider.FFIProvider$SystemProviderSingletonHolder.<clinit>(FFIProvider.java:57)
    [ERROR] 	at jnr.ffi.provider.FFIProvider.getSystemProvider(FFIProvider.java:35)
    [ERROR] 	at jnr.ffi.LibraryLoader.create(LibraryLoader.java:89)
    [ERROR] 	at jnr.unixsocket.Native.<clinit>(Native.java:76)
    [ERROR] 	at jnr.unixsocket.UnixSocketChannel.<init>(UnixSocketChannel.java:101)
    [ERROR] 	at jnr.unixsocket.UnixSocketChannel.open(UnixSocketChannel.java:60)
    [ERROR] 	at io.fabric8.maven.docker.access.util.LocalSocketUtil.canConnectUnixSocket(LocalSocketUtil.java:38)
    [ERROR] 	at io.fabric8.maven.docker.access.DockerConnectionDetector$UnixSocketDockerHostProvider.getConnectionParameter(DockerConnectionDetector.java:113)
    [ERROR] 	at io.fabric8.maven.docker.access.DockerConnectionDetector.detectConnectionParameter(DockerConnectionDetector.java:82)
    [ERROR] 	at io.fabric8.maven.docker.service.DockerAccessFactory.createDockerAccess(DockerAccessFactory.java:34)
    [ERROR] 	at io.fabric8.maven.docker.AbstractDockerMojo.execute(AbstractDockerMojo.java:274)
    [ERROR] 	at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:137)
    [ERROR] 	at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2(MojoExecutor.java:370)
    [ERROR] 	at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute(MojoExecutor.java:351)
    [ERROR] 	at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:215)
    [ERROR] 	at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:171)
    [ERROR] 	at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:163)
    [ERROR] 	at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)
    [ERROR] 	at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
    [ERROR] 	at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:56)
    [ERROR] 	at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
    [ERROR] 	at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:298)
    [ERROR] 	at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:192)
    [ERROR] 	at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:105)
    [ERROR] 	at org.apache.maven.cli.MavenCli.execute(MavenCli.java:960)
    [ERROR] 	at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:293)
    [ERROR] 	at org.apache.maven.cli.MavenCli.main(MavenCli.java:196)
    [ERROR] 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    [ERROR] 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    [ERROR] 	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    [ERROR] 	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    [ERROR] 	at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:282)
    [ERROR] 	at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:225)
    [ERROR] 	at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:406)
    [ERROR] 	at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:347)
    
  4. I checked out source branch of PR Try again using debian:8 for older glibc #140 and built / installed it (on CentOS 7.9):

    $ mvn install
    ...
    [INFO] ------------------------< com.github.jnr:jffi >-------------------------
    [INFO] Building jffi 1.3.11-SNAPSHOT
    [INFO] --------------------------------[ jar ]---------------------------------
    ...
    [INFO] --- maven-antrun-plugin:3.0.0:run (default) @ jffi ---
    [INFO] Executing tasks
    ...
    [INFO]     [unzip] Expanding: /ws/jnr/jffi/archive/jffi-x86_64-Linux.jar into /ws/jnr/jffi/target
    ...
    [INFO] Executed tasks
    [INFO]
    [INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ jffi ---
    [INFO] Not compiling test sources
    [INFO]
    [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ jffi ---
    [INFO] Tests are skipped.
    [INFO]
    [INFO] --- maven-bundle-plugin:2.4.0:manifest (native-assembly) @ jffi ---
    [WARNING] Manifest com.github.jnr:jffi:jar:1.3.11-SNAPSHOT : No sub JAR or directory jni
    [INFO]
    [INFO] --- maven-jar-plugin:3.2.0:jar (default-jar) @ jffi ---
    [INFO] Building jar: /ws/jnr/jffi/target/jffi-1.3.11-SNAPSHOT.jar
    [INFO]
    [INFO] --- maven-assembly-plugin:2.2:single (jffi-complete) @ jffi ---
    [INFO] Reading assembly descriptor: src/main/assembly/complete.xml
    [INFO] Building jar: /ws/jnr/jffi/target/jffi-1.3.11-SNAPSHOT-complete.jar
    [INFO]
    [INFO] --- maven-assembly-plugin:2.2:single (native-assembly) @ jffi ---
    [INFO] Reading assembly descriptor: src/main/assembly/native.xml
    [INFO] Building jar: /ws/jnr/jffi/target/jffi-1.3.11-SNAPSHOT-native.jar
    [INFO]
    [INFO] --- maven-install-plugin:2.4:install (default-install) @ jffi ---
    [INFO] Installing /ws/jnr/jffi/target/jffi-1.3.11-SNAPSHOT.jar to /repository/com/github/jnr/jffi/1.3.11-SNAPSHOT/jffi-1.3.11-SNAPSHOT.jar
    [INFO] Installing /ws/jnr/jffi/pom.xml to /repository/com/github/jnr/jffi/1.3.11-SNAPSHOT/jffi-1.3.11-SNAPSHOT.pom
    [INFO] Installing /ws/jnr/jffi/target/jffi-1.3.11-SNAPSHOT-complete.jar to /repository/com/github/jnr/jffi/1.3.11-SNAPSHOT/jffi-1.3.11-SNAPSHOT-complete.jar
    [INFO] Installing /ws/jnr/jffi/target/jffi-1.3.11-SNAPSHOT-native.jar to /repository/com/github/jnr/jffi/1.3.11-SNAPSHOT/jffi-1.3.11-SNAPSHOT-native.jar
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  10.305 s
    [INFO] Finished at: 2023-03-09T12:07:19+03:00
    [INFO] ------------------------------------------------------------------------
    
  5. I have modified my maven project (the one I use to build docker image) this way:

    --- a/pom.xml
    +++ b/pom.xml
    @@ -67,7 +67,8 @@
             <maven-deploy-plugin.version>3.0.0</maven-deploy-plugin.version>
             <versions-maven-plugin.version>2.11.0</versions-maven-plugin.version>
             <build-helper-maven-plugin.version>3.3.0</build-helper-maven-plugin.version>
    -        <docker-maven-plugin.version>0.40.3</docker-maven-plugin.version>
    +        <docker-maven-plugin.version>0.42.0</docker-maven-plugin.version>
    +        <jffi.version>1.3.11-SNAPSHOT</jffi.version>
     
             <!-- Skip integration tests by default -->
             <skipITs>true</skipITs>
    @@ -417,6 +418,19 @@
                         <groupId>io.fabric8</groupId>
                         <artifactId>docker-maven-plugin</artifactId>
                         <version>${docker-maven-plugin.version}</version>
    +                    <dependencies>
    +                        <dependency>
    +                            <groupId>com.github.jnr</groupId>
    +                            <artifactId>jffi</artifactId>
    +                            <version>${jffi.version}</version>
    +                        </dependency>
    +                        <dependency>
    +                            <groupId>com.github.jnr</groupId>
    +                            <artifactId>jffi</artifactId>
    +                            <version>${jffi.version}</version>
    +                            <classifier>native</classifier>
    +                        </dependency>
    +                    </dependencies>
                     </plugin>
                     <plugin>
                         <groupId>org.sonarsource.scanner.maven</groupId>
  6. After modification of maven project, I was able to successfully build docker image:

    $ mvn clean package -P docker
    ...
    [INFO] --- docker-maven-plugin:0.42.0:build (build-docker-image) @ geode-image ---
    [INFO] Building tar: /ws/dimension/geode-docker/geode-image/target/docker/nrc3ldockreg01vm.am.tsacorp.com/18081/ebpp/v4/geode/1.6.0/tmp/docker-build.tar
    [INFO] DOCKER> [nrc3ldockreg01vm.am.tsacorp.com:18081/ebpp/v4/geode:1.6.0]: Created docker-build.tar in 340 milliseconds
    ...
    [INFO] DOCKER> Successfully built 5a824972ed43
    ...
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  15.504 s
    [INFO] Finished at: 2023-03-09T12:12:27+03:00
    [INFO] ------------------------------------------------------------------------
    

@headius
Copy link
Member

headius commented Mar 9, 2023

@mabrarov This is excellent information and exactly what I was looking for, thank you! I will proceed with putting out a jffi release and start to test it in the rest of the jnr-* family.

@headius
Copy link
Member

headius commented Feb 9, 2024

Ah there is a wrinkle here I had not noticed: this is in libffi code.

It may make more sense for us to explicitly disable HAVE_MEMFD_CREATE during the build since we don't really want to be modifying libffi code directly.

@headius
Copy link
Member

headius commented Feb 9, 2024

Another approach: call the kernel function directly rather than binding to the libc version:

memfd = syscall(SYS_memfd_create, "", 0);

https://www.rapid7.com/blog/post/2019/12/24/memory-laundering-is-cleaner-better/

I'm digging around to figure out what the implications are of avoiding memfd_create.

@headius
Copy link
Member

headius commented Feb 9, 2024

More background from reading code and information about memfd_create...

This is being used in libffi to generate callbacks for functions that need them, in order to take two independent functions and make a "closure" so the one can call the other by pointer. In order to get around execution checks, a file is filled with the closure stub code and then mapped into memory as executable. The old approach uses mkstemp or similar to create that file, immediately unlinking it. The use of memfd_create skips the tempfile and immediately presents a file-like fd that can be used in the same way.

The old approach should work fine, but will require privileges to access a temp location. Luckily, jffi already requires this in order to unpack an appropriate platform binary which is then loaded in as executable code.

@headius
Copy link
Member

headius commented Feb 12, 2024

Ok, the syscall approach will also not work because the kernel in RHEL/CentOS 7 predates the addition of this function.

I want to verify that there's no impact from just dropping its use altogether.

@headius
Copy link
Member

headius commented Feb 12, 2024

I probably am missing a way to do this, but I just filed libffi/libffi#826 to try to get libffi to add memfd_create as a disableable feature.

The down sides as I know them currently:

  • SELinux and similar environments will have issues with the use of a tmpfile to get the same functionality. However already have issues with SELinux when we unpack our library to the systemwide temp location and then try to load it.
  • The non-memfd_create approach may be less secure, since there's a gap between creating the tmpfile and unlinking it. This might be possible to mitigate with a separate patch in libffi, but that is an open question.

@atgreen
Copy link

atgreen commented Feb 13, 2024

Disable it thusly: ./configure 'ac_cv_func_memfd_create=no'

@atgreen
Copy link

atgreen commented Feb 13, 2024

I should mention that in the latest version of libffi, the temp file approach is just a backup for when static trampolines aren't available for some reason. Static trampolines are a relatively new way to implement closures so they don't require RWX memory. It's best explained here: https://blog.lazym.io/2021/07/29/Cast-a-Closure-to-a-Function-Pointer-How-libffi-closure-works/

@headius
Copy link
Member

headius commented Feb 13, 2024

@atgreen Thank you for your help! That should be sufficient for us to build a binary that works even on older glibc/linux without memfd_create...if we even have to?

Static trampolines are a relatively new way to implement closures so they don't require RWX memory. It's best explained here

Ahh this appears to be (similar to?) the "double mmap" strategy I read about in a few other posts. So are you saying that latest libffi no longer depends on memfd_create? If so, perhaps we can simply update libffi and build a binary that supports those older platforms?

I'll push a PR that updates libffi and then @PerfectSlayer @rosti-il @mabrarov and others here can test it out on their environments.

@headius
Copy link
Member

headius commented Feb 13, 2024

There are now builds of jffi (with updated libffi) for x86_64, arm, and aarch64 that could be tested (I think only the x86_64 is relevant to this issue) here: https://github.com/jnr/jffi/actions/runs/7889009015?pr=153

@headius
Copy link
Member

headius commented Feb 13, 2024

I will need to find another OpenJDK distribution that publishes i386 binaries for Java 8 on Debian to get that build working.

@headius
Copy link
Member

headius commented Feb 13, 2024

@mabrarov @PerfectSlayer @kingluo @RainerGanss @DManstrator @Sobakaa Could you confirm whether the built binaries from #153 work for you under CentOS/RHEL 7?

See the binaries at the bottom of this page: https://github.com/jnr/jffi/actions/runs/7889009015?pr=153

@richardstartin
Copy link

Hi @headius I took a look at the x64 and arm64 binaries (I used readelf, which is in binutils) and the latest change made things worse because there's now a GLIBC 2.27 symbol (memfd_create) exported by the x64 binary:

# readelf -sW libjffi-1.2.so | grep GLIBC | rev | cut -d '_' -f 1 | rev | sort | uniq
2.14
2.14 (5)
2.2.5
2.2.5 (2)
2.27
2.27 (3)
2.7
2.7 (4)
# readelf -sW libjffi-1.2.so | grep GLIBC_2.27
     6: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND memfd_create@GLIBC_2.27 (3)
   165: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND memfd_create@@GLIBC_2.27

and still a GLIBC 2.27 symbol (memfd_create) exported by the arm64 binary:

# readelf -sW libjffi-1.2-arm64.so | grep GLIBC | rev | cut -d '_' -f 1 | rev | sort | uniq
2.17
2.17 (2)
2.27

# readelf -sW libjffi-1.2-arm64.so | grep GLIBC_2.27
     7: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND memfd_create@GLIBC_2.27 (3)
   247: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND memfd_create@@GLIBC_2.27

So the binaries can't be linked on systems with glibc versions older than 2.27.

Though you're going to want to update the libffi dependency at some point anyway, I think that leaving libffi and the build images alone and applying the command mentioned above, (assuming ./configure 'ac_cv_func_memfd_create=no' ensures HAVE_MEMFD_CREATE is undefined during compilation) would resolve this issue. @atgreen does the command you above have this effect?

@headius
Copy link
Member

headius commented Feb 14, 2024

@richardstartin Aha, thank you for that (and for providing your command lines so I can check this myself).

I will do a separate PR with existing libffi that configures without memfd_create and we'll see if that looks better

headius added a commit that referenced this issue Feb 14, 2024
Workaround for #138 until we can come up with a better solution.
@headius
Copy link
Member

headius commented Feb 14, 2024

Ok I've merged the build fixes to master, rebased libffi update for another day, and pushed #155 to add that configure line to the build.

@headius
Copy link
Member

headius commented Feb 14, 2024

@richardstartin The new binary looks better on x86_64:

$ readelf -sW jni/x86_64-Linux/libjffi-1.2.so | grep GLIBC | rev | cut -d '_' -f 1 | rev | sort | uniq
2.14
2.14 (4)
2.2.5
2.2.5 (2)
2.7
2.7 (3)

@richardstartin
Copy link

It was the aarch64 and arm binaries causing problems before (and loongarch64 but I think we can ignore that one) #138 (comment)

@headius
Copy link
Member

headius commented Feb 14, 2024

aarch64 looks ok too:

[] ~/jni/aarch64-Linux $ readelf -sW libjffi-1.2.so | grep GLIBC | rev | cut -d '_' -f 1 | rev | sort | uniq
2.17
2.17 (2)

@headius
Copy link
Member

headius commented Feb 14, 2024

I don't know how best to update the i386 build but I will pull in the new binaries for x86_64, arm, and aarch64 and start the process of release testing.

@headius headius linked a pull request Feb 14, 2024 that will close this issue
headius added a commit that referenced this issue Feb 14, 2024
This pulls in binaries for x86_64, aarch64, and arm that have been
configured to avoid the use of memfd_create, a glibc 2.27 feature
not available on some older (but still-supported) RHEL and CentOS
versions. The i386 build is not updated due to issues finding an
appropriate Java 8 build.

See #138.
at055612 added a commit to at055612/lmdbjava that referenced this issue Feb 28, 2024
Potentially fixes this jnr/jffi#138
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
10 participants