Please review this RFE that alters the visibility of JNI entrypoints to hidden 
when a shared library
is created using static JDK libraries.

RFE: https://bugs.openjdk.java.net/browse/JDK-8239563

All JNI entrypoints that exist in JDK static libraries are declared as exported 
or visible. 
If a dynamic library is built from these static libraries, we end up with many 
exported
symbols even though we don't want to provide access to these entrypoints.  

This RFE will change the declarations of JNIEXPORT for libraries built when 
STATIC_BUILD
to be hidden. This will still allow linking of these functions into native 
libraries but not
export the JDK symbols outside of the generated libs.

BACKGROUND:

In JDK8 the JNI specification and JDK implementation was enhanced to support 
static JNI libraries
but we didn’t consider the issue of visibility of JNI entrypoint symbols.

   https://bugs.openjdk.java.net/browse/JDK-8005716

If developers use these static JDK libraries in order to produce a custom 
shared library, all of the
JNIEXPORTS will be exposed by this library even if the developer did not choose 
to export these.
This is a security issue and a potential problem if this library is mixed with 
other libraries containing
these symbols.


Here’s a proposed patch to implement this RFE.  I realize that exposing 
STATIC_BUILD in a public
header file “jni_md.h” is a potential issue.  I welcome alternate suggestions.  
If this is a real serious
issue, we could consider renaming this to JNI_STATIC_BUILD and going through a 
CSR.  The problem
with a CSR is that this fix will likely be backported to JDK 8 and 11 making a 
bump in the JNI version is
big problem.  I tried altering jni_util.h where other STATIC_BUILD macros are 
defined but ran into
issues where there were visibility mismatches between javah generated header 
files and “C” code 
that consumed it.  This is because jni.h is included in these header files 
without jni_util.h.


diff --git a/src/java.base/unix/native/include/jni_md.h 
b/src/java.base/unix/native/include/jni_md.h
--- a/src/java.base/unix/native/include/jni_md.h
+++ b/src/java.base/unix/native/include/jni_md.h
@@ -31,10 +31,18 @@
 #endif
 #if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && 
(__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
   #ifdef ARM
-    #define JNIEXPORT     
__attribute__((externally_visible,visibility("default")))
+    #ifndef STATIC_BUILD
+      #define JNIEXPORT     
__attribute__((externally_visible,visibility("default")))
+    #else
+      #define JNIEXPORT     __attribute__((visibility("hidden")))
+    #endif
     #define JNIIMPORT     
__attribute__((externally_visible,visibility("default")))
   #else
-    #define JNIEXPORT     __attribute__((visibility("default")))
+    #ifndef STATIC_BUILD
+      #define JNIEXPORT     __attribute__((visibility("default")))
+    #else
+      #define JNIEXPORT     __attribute__((visibility("hidden")))
+    #endif
     #define JNIIMPORT     __attribute__((visibility("default")))
   #endif
 #else
diff --git a/src/java.base/windows/native/include/jni_md.h 
b/src/java.base/windows/native/include/jni_md.h
--- a/src/java.base/windows/native/include/jni_md.h
+++ b/src/java.base/windows/native/include/jni_md.h
@@ -26,7 +26,12 @@
 #ifndef _JAVASOFT_JNI_MD_H_
 #define _JAVASOFT_JNI_MD_H_
 
+#ifndef STATIC_BUILD
 #define JNIEXPORT __declspec(dllexport)
+#else
+#define JNIEXPORT
+#endif
+
 #define JNIIMPORT __declspec(dllimport)
 #define JNICALL __stdcall

I’ve build the JDK 15 static libraries with this patch and have confirmed that 
the symbols are no longer present
in a generated shared library on Windows, Mac and Linux.


Bob.


Reply via email to