Skip to content

Commit

Permalink
Only analyse binary to determine hardfloat vs. softfloat on arm
Browse files Browse the repository at this point in the history
The ELFAnalyser analyses the java binary to determine, whether the
hardfloat/softfloat flags are set. This causes issues if a security
manager is in place and limits file accessibility.

The JNA code base needs read access on the /proc/self/exe symlink and
the referenced binary.

This change reduces the cases where the executing binary is read. On
platforms, that don't need it, the detection step is skipped.

Close: java-native-access#825
  • Loading branch information
matthiasblaesing committed Jun 25, 2017
1 parent ba176a8 commit 4603f83
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 40 deletions.
26 changes: 13 additions & 13 deletions src/com/sun/jna/Platform.java
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ else if (osName.equalsIgnoreCase("netbsd")) {
C_LIBRARY_NAME = osType == WINDOWS ? "msvcrt" : osType == WINDOWSCE ? "coredll" : "c";
MATH_LIBRARY_NAME = osType == WINDOWS ? "msvcrt" : osType == WINDOWSCE ? "coredll" : "m";
HAS_DLL_CALLBACKS = osType == WINDOWS;
ARCH = getCanonicalArchitecture(System.getProperty("os.arch"), isSoftFloat());
ARCH = getCanonicalArchitecture(System.getProperty("os.arch"));
RESOURCE_PREFIX = getNativeLibraryResourcePrefix();
}
private Platform() { }
Expand Down Expand Up @@ -236,7 +236,7 @@ public static final boolean isMIPS() {
return false;
}

static String getCanonicalArchitecture(String arch, boolean softfloat) {
static String getCanonicalArchitecture(String arch) {
arch = arch.toLowerCase().trim();
if ("powerpc".equals(arch)) {
arch = "ppc";
Expand All @@ -256,22 +256,26 @@ else if ("x86_64".equals(arch) || "amd64".equals(arch)) {
arch = "ppc64le";
}
// Map arm to armel if the binary is running as softfloat build
if("arm".equals(arch) && softfloat) {
if("arm".equals(arch) && isSoftFloat()) {
arch = "armel";
}


return arch;
}

private static boolean isSoftFloat() {
static boolean isSoftFloat() {
try {
File self = new File("/proc/self/exe");
ELFAnalyser ahfd = ELFAnalyser.analyse(self.getCanonicalPath());
return ahfd.isArmSoftFloat();
if (self.exists()) {
ELFAnalyser ahfd = ELFAnalyser.analyse(self.getCanonicalPath());
return ahfd.isArmSoftFloat();
}
} catch (IOException ex) {
// asume hardfloat
Logger.getLogger(Platform.class.getName()).log(Level.FINE, null, ex);
Logger.getLogger(Platform.class.getName()).log(Level.INFO, "Failed to read '/proc/self/exe' or the target binary.", ex);
} catch (SecurityException ex) {
// asume hardfloat
Logger.getLogger(Platform.class.getName()).log(Level.INFO, "SecurityException while analysing '/proc/self/exe' or the target binary.", ex);
}
return false;
}
Expand All @@ -295,12 +299,8 @@ static String getNativeLibraryResourcePrefix() {
@param name from <code>os.name</code> System property
*/
static String getNativeLibraryResourcePrefix(int osType, String arch, String name) {
return getNativeLibraryResourcePrefix(osType, arch, name, isSoftFloat());
}

static String getNativeLibraryResourcePrefix(int osType, String arch, String name, boolean isSoftfloat) {
String osPrefix;
arch = getCanonicalArchitecture(arch, isSoftfloat);
arch = getCanonicalArchitecture(arch);
switch(osType) {
case Platform.ANDROID:
if (arch.startsWith("arm")) {
Expand Down
56 changes: 29 additions & 27 deletions test/com/sun/jna/PlatformTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,71 +31,73 @@ public class PlatformTest extends TestCase {
public void testOSPrefix() {
assertEquals("Wrong resource path", "win32-x86",
Platform.getNativeLibraryResourcePrefix(Platform.WINDOWS,
"x86", "Windows", false));
"x86", "Windows"));
assertEquals("Wrong resource path Windows/i386", "win32-x86",
Platform.getNativeLibraryResourcePrefix(Platform.WINDOWS,
"i386", "Windows", false));
"i386", "Windows"));
assertEquals("Wrong resource path Windows CE/arm", "w32ce-arm",
Platform.getNativeLibraryResourcePrefix(Platform.WINDOWSCE,
"arm", "Windows CE", false));
"arm", "Windows CE"));
assertEquals("Wrong resource path Mac/x86", "darwin",
Platform.getNativeLibraryResourcePrefix(Platform.MAC,
"x86", "Darwin", false));
"x86", "Darwin"));
assertEquals("Wrong resource path Mac/x86", "darwin",
Platform.getNativeLibraryResourcePrefix(Platform.MAC,
"i386", "Darwin", false));
"i386", "Darwin"));
assertEquals("Wrong resource path Mac/x86_64", "darwin",
Platform.getNativeLibraryResourcePrefix(Platform.MAC,
"x86_64", "Mac", false));
"x86_64", "Mac"));
assertEquals("Wrong resource path Solaris/sparc", "sunos-sparc",
Platform.getNativeLibraryResourcePrefix(Platform.SOLARIS,
"sparc", "Solaris", false));
"sparc", "Solaris"));
assertEquals("Wrong resource path SunOS/sparcv9", "sunos-sparcv9",
Platform.getNativeLibraryResourcePrefix(Platform.SOLARIS,
"sparcv9", "SunOS", false));
"sparcv9", "SunOS"));
assertEquals("Wrong resource path Linux/i386", "linux-x86",
Platform.getNativeLibraryResourcePrefix(Platform.LINUX,
"i386", "Linux/Gnu", false));
"i386", "Linux/Gnu"));
assertEquals("Wrong resource path Linux/x86", "linux-x86",
Platform.getNativeLibraryResourcePrefix(Platform.LINUX,
"x86", "Linux", false));
"x86", "Linux"));
assertEquals("Wrong resource path Linux/x86", "linux-x86-64",
Platform.getNativeLibraryResourcePrefix(Platform.LINUX,
"x86_64", "Linux", false));
"x86_64", "Linux"));
assertEquals("Wrong resource path Linux/x86", "linux-x86-64",
Platform.getNativeLibraryResourcePrefix(Platform.LINUX,
"amd64", "Linux", false));
"amd64", "Linux"));
assertEquals("Wrong resource path Linux/ppc", "linux-ppc",
Platform.getNativeLibraryResourcePrefix(Platform.LINUX,
"powerpc", "Linux", false));
"powerpc", "Linux"));
assertEquals("Wrong resource path Linux/sparcv9", "linux-sparcv9",
Platform.getNativeLibraryResourcePrefix(Platform.LINUX,
"sparcv9", "Linux", false));
assertEquals("Wrong resource path Linux/arm (hardfloat)", "linux-arm",
Platform.getNativeLibraryResourcePrefix(Platform.LINUX,
"arm", "Linux/Gnu", false));
assertEquals("Wrong resource path Linux/arm (softfloat)", "linux-armel",
Platform.getNativeLibraryResourcePrefix(Platform.LINUX,
"arm", "Linux/Gnu", true));
"sparcv9", "Linux"));
if (Platform.isSoftFloat()) {
assertEquals("Wrong resource path Linux/arm (softfloat)", "linux-armel",
Platform.getNativeLibraryResourcePrefix(Platform.LINUX,
"arm", "Linux/Gnu"));
} else {
assertEquals("Wrong resource path Linux/arm (hardfloat)", "linux-arm",
Platform.getNativeLibraryResourcePrefix(Platform.LINUX,
"arm", "Linux/Gnu"));
}
assertEquals("Wrong resource path OpenBSD/x86", "openbsd-x86",
Platform.getNativeLibraryResourcePrefix(Platform.OPENBSD,
"x86", "OpenBSD", false));
"x86", "OpenBSD"));
assertEquals("Wrong resource path FreeBSD/x86", "freebsd-x86",
Platform.getNativeLibraryResourcePrefix(Platform.FREEBSD,
"x86", "FreeBSD", false));
"x86", "FreeBSD"));
assertEquals("Wrong resource path GNU/kFreeBSD/x86", "kfreebsd-x86",
Platform.getNativeLibraryResourcePrefix(Platform.KFREEBSD,
"x86", "GNU/kFreeBSD", false));
"x86", "GNU/kFreeBSD"));
assertEquals("Wrong resource path NetBSD/x86", "netbsd-x86",
Platform.getNativeLibraryResourcePrefix(Platform.NETBSD,
"x86", "NetBSD", false));
"x86", "NetBSD"));
assertEquals("Wrong resource path Linux/armv7l (android)", "android-arm",
Platform.getNativeLibraryResourcePrefix(Platform.ANDROID,
"armv7l", "Linux", false));

"armv7l", "Linux"));
assertEquals("Wrong resource path other/other", "name-ppc",
Platform.getNativeLibraryResourcePrefix(Platform.UNSPECIFIED,
"PowerPC", "Name Of System", false));
"PowerPC", "Name Of System"));

}

Expand Down

0 comments on commit 4603f83

Please sign in to comment.