Skip to content

NativeLibraryLoader fails due to no write permissions #2302

Open
@terranprog

Description

@terranprog

Running Linux.
I am getting an exception when jme tries to extract a native library to a temp folder.

Aug 15, 2024 5:40:32 PM com.jme3.system.JmeDesktopSystem initialize
INFO: Running on jMonkeyEngine 3.7.0-beta1.2.2
 * Branch: HEAD
 * Git Hash: 5cadb88
 * Build Date: 2024-07-30
Exception in thread "AWT-EventQueue-0" java.io.UncheckedIOException: Failed to extract native library to: /tmp/jme3/natives_8946616b/libbulletjme-x86_64.so
	at com.jme3.system.NativeLibraryLoader.loadNativeLibrary(NativeLibraryLoader.java:534)
	at com.jme3.system.JmeDesktopSystem.initialize(JmeDesktopSystem.java:290)
	at com.jme3.system.JmeDesktopSystem.newContext(JmeDesktopSystem.java:212)
	at com.jme3.system.JmeSystem.newContext(JmeSystem.java:175)
	at com.jme3.app.LegacyApplication.createCanvas(LegacyApplication.java:560)
	at scamsoft.minecraft.terrain3d.Terrain3D.<init>(Terrain3D.java:112)
	at scamsoft.minecraft.terrain3d.gui.TerrainGui.lambda$main$12(TerrainGui.java:886)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Caused by: java.nio.file.NoSuchFileException: /tmp/jme3/natives_8946616b/libbulletjme-x86_64.so
	at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
	at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
	at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
	at java.base/sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:218)
	at java.base/java.nio.file.spi.FileSystemProvider.newOutputStream(FileSystemProvider.java:484)
	at java.base/java.nio.file.Files.newOutputStream(Files.java:228)
	at java.base/java.nio.file.Files.copy(Files.java:3160)
	at com.jme3.system.NativeLibraryLoader.loadNativeLibrary(NativeLibraryLoader.java:506)

The application is running as a non-root user.

The /tmp/jme folder has permissions drwxr-xr-x 5 root root

In other words:

  • root has ownership of /tmp/jme
  • root has write permissions
  • other users have read permissions but not write

The logic in NativeLibraryLoader.getExtractionFolder() has a couple of holes that are causing this to fail.

  • The code checks if the user has write permission to the temp folder (/tmp) but doesn't check write permissions to the /tmp/jme subfolder (it assumes write permissions exist)
  • There is logic to catch any exceptions while creating the temp folder and to call setExtractionFolderToUserCache() instead. The problem is that the call to extractionFolder.mkdir() does not throw an exception if it fails; but instead returns false. And the JME code does not check the result of this call.

Some suggestions for improvements:

  • The /tmp/jme folder is shared between all jme applications. This is probably not a good idea as it seems that whatever user creates the /tmp/jme folder does not give write permissions to other users. A better scheme would be to create completely independent temp folders e.g. /tmp/jme_natives_[hash]
  • Calls to mkdir should be checked for failure and handled accordingly e.g. throw an exception so setExtractionFolderToUserCache() will be called instead

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions