JEP draft: Prepare to Restrict The Use of JNI

Ryan Schmitt rschmitt at pobox.com
Tue Aug 29 23:10:10 UTC 2023


My interpretation of Ron's response to my earlier message is that, although
none of these issues with JNI are essentially new, they will represent a
larger and larger attack surface over time as more of the Java Platform
itself is written or rewritten in Java in the interests of maintainability
and faster evolution. These types of long-standing risks aren't that big of
a deal, until suddenly one day they're a *very* big deal, and they are
being discussed in US Senate hearings [1].

An implied benefit of this policy is that it will make JNI less important
in the long run, since a more maintainable Java Platform means a more
feature-rich Java Platform, with fewer gaps that need to be filled in with
JNI libraries. (Still, I'd personally like to see a way for vendors to
create trusted JNI libraries that don't require opt-in, but I think that's
ultimately unrealistic.)

[1] https://www.youtube.com/watch?v=8Y9OOTA-4mE

On Tue, Aug 29, 2023 at 3:07 PM CC <4evnyuij at gmail.com> wrote:

> I've looked through the JEP a bit more, and can confidently say that this
> will be the first step towards a future I, personally, would not want to
> live in regarding java.
>
> > Unfortunately, any interaction *at all* between Java code and native
> code is risky because /it can compromise the integrity of applications and
> the Java Platform itself/. According to the policy of (
> https://openjdk.org/jeps/8305968), all JDK features that are capable of
> breaking integrity must obtain explicit approval from the end user or the
> application assembler.
>
> So what about reflection? Method handles? Accessing even just the smallest
> of internals? Unsafe? All of those could compromise the integrity of the
> java platform, and should therefore be locked behind the library user
> accepting them to be used. Why aren't they locked behind flags?
>
> > Calling native code can lead to arbitrary undefined behavior
> <https://en.wikipedia.org/wiki/Undefined_behavior>, including JVM
> crashes. Such problems cannot be prevented by the Java runtime or caught by
> Java code.
> Unsafe. Misconfigured method handles.
>
> > Native code and Java code often exchange data through byte buffers
> <https://docs.oracle.com/en/java/javase/20/docs/specs/jni/functions.html#newdirectbytebuffer>,
> which are regions of memory not managed by the JVM's garbage collector.
> Native code can produce a byte buffer that is backed by an invalid region
> of memory, and using the byte buffer in Java code is practically certain to
> cause undefined behavior.
> The foreign memory API will allow you to do that directly from the comfort
> of java.
>
> > Native code could use the JNI API to access fields
> <https://docs.oracle.com/en/java/javase/20/docs/specs/jni/functions.html#accessing-fields-of-objects>
> and call methods
> <https://docs.oracle.com/en/java/javase/20/docs/specs/jni/functions.html#calling-instance-methods>
> without any access checks by the JVM or even change the values of final
> fields long after they are initialized because the implementation of JNI
> does not perform the appropriate checks. Java code that uses JNI could
> therefore circumvent any of the invariants established through strong
> encapsulation of any other Java code.
> So what? There are legitimate reasons for this, changing internal fields
> may sometimes be required to make something work the way you want. There is
> no reason to use this as an argument against JNI, because it legitimately
> is a good use case. While I agree that changing a String instance's data
> array would be a bit silly, that example is also about the least practical
> example of this.
>
> > Native code which uses certain functions of the JNI API incorrectly
> (principally GetPrimitiveArrayCritical
> <https://docs.oracle.com/en/java/javase/20/docs/specs/jni/functions.html#getprimitivearraycritical-releaseprimitivearraycritical>
> and GetStringCritical
> <https://docs.oracle.com/en/java/javase/20/docs/specs/jni/functions.html#getstringcritical-releasestringcritical>)
> may cause undesirable behavior by the garbage collector
> <https://shipilev.net/jvm/anatomy-quarks/9-jni-critical-gclocker/> that
> can manifest at any time during the program's lifetime.
> This can be said about a lot of other things as well; A feature is not at
> fault for a bad programmer using it.
>
> Other arguments in this thread are so extremely out of touch with how the
> modern java world works, they have me questioning the timeline I am living
> in.
>
> This thread is a prideful demonstration of the sheer incompetence managing
> the Java specification, and I am ashamed even being apart of it.
>
> This will be my final message on the topic, lest these changes run into
> the danger of being merged.
>
> Constantin
>
> Am Di., 29. Aug. 2023 um 18:16 Uhr schrieb Alex Buckley <
> alex.buckley at oracle.com>:
>
>> On 8/29/2023 8:47 AM, Quân Anh Mai wrote:
>> > There is a huge difference between --add-opens and
>> > --enable-native-access here. While the sole purpose of --add-opens is
>> to
>> > break encapsulation and open implementation details, dependence on
>> which
>> > is a major factor causing the friction of migration from 8 to 9, the
>> > purpose of JNI is not to break anything, but to simply enable native
>> > accesses from Java. While encapsulation breakage is possible in JNI,
>> > equating it as its sole purpose seems illogical. As a result, forcing
>> > the users to treat it similarly as --add-opens and friends seems not to
>> > be reasonable to me.
>>
>> We are not saying that breaking encapsulation is the sole purpose of
>> JNI. We are saying that the use of native code, while sometimes the only
>> way to do something, is risky. The JEP identifies four risks --
>> https://openjdk.org/jeps/8307341#Motivation -- of which the first two --
>> undefined behavior and bad buffers -- are by far the worst.
>>
>> We are then saying something further: the risks are so high that the
>> user should explicitly agree to take them.
>>
>> Alex
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/jdk-dev/attachments/20230829/f82b41f3/attachment.htm>


More information about the jdk-dev mailing list