Fix proposal for bug JDK-8221642
Mandy Chung
mandy.chung at oracle.com
Thu Jan 27 16:45:59 UTC 2022
Hi Andreas,
What methods are you calling that throws NPE? Do you have the stack
trace to share?
The spec of AccessibleObject was updated for JDK-8221530 if there is no
caller frame when calling from JNI:
"The check when invoked by JNI code with no Java class on the stack only
succeeds if the member and the declaring class are public, and the class
is in a package that is exported to all modules."
I think AccessibleObject::canAccess, setAccessible, trySetAccessible
should follow the same rule.
Mandy
On 1/27/22 2:19 AM, Andreas Rosenberg wrote:
> Hi,
>
> this is my first posting regarding to JDK contribution, so this may be the wrong place to ask.
> Please point me in the right direction in this case.
>
> We are using Java rather heavily via JNI on a custom application. For a long time we did stick to JRE 1.8
> for various reasons. My task is to plan an upgrade to a more recent JDK version and while doing some
> test I encountered bugs related to this: JDK-8227491 (JNI - caller sensitive methods).
>
> We are parsing Java class files to auto gen the JNI code for our application, and are also using reflection.
> The workaround given is clumsy and needs manual intervention, so I was looking for a more elegant solution.
>
> The problem is: a caller sensitive method wants to determine the caller class for security checks. In case of
> a JNI call no Java stack frame exists, so the JVM function "jclass JVM_GetCallerClass(JNIEnv* env)" answers NULL
> which leads to NPEs.
>
> My idea is this: create an internal proxy class inside "java.base" that reflects this case
> (e.g. "java.lang.NativeCall" or "java.lang.NativeCode").
> This class is final and implements nothing.
>
> Then "jclass JVM_GetCallerClass(JNIEnv* env)" (jvm.cpp) could be modified and instead of answering NULL
> in case of a JNI call, it should do this to answer the class proxy:
>
> return JVM_FindClassFromBootLoader(env, "java/lang/NativeCall");
>
> This would have the following advantages:
> - JNI code could again simply call "caller sensitive methods" without the need to make an additional wrapper class
> - it would be more a expressive way on the Java side to detect "the callee is native code" than checking for null
> - it would fit better into the framework
>
> I already applied this fix on my own copy of the JDK 17 sources and it works pretty well for us.
>
> As there are probably security considerations involved, advice from experts is required.
> But from my understanding the Java security model is designed for the main app being writing in Java.
> In this case there are always Java stacks frames available as parents for caller sensitive methods, so
> the proposed fix would not affect the behavior. This assumes that "GetCallerClass" only answers
> NULL for the JNI case. This needs verification.
>
> If the main app is native code which uses JNI, the Java security model can only affect the Java part and
> as soon as an additional Java stack frame has been generated a regular Java class will be found and
> the "standard behavior" should apply again.
>
> Comments appreciated.
>
> It this fix looks reasonable, what are the steps to get it implemented and integrated into the official
> source tree?
>
> Best regards,
> Andy
>
>
More information about the core-libs-dev
mailing list