Minor thoughts (Re: [External] : Re: JEP draft: Prepare to Restrict The Use of JNI

Ron Pressler ron.pressler at oracle.com
Wed Aug 30 18:08:41 UTC 2023



> On 30 Aug 2023, at 17:21, Rony G. Flatscher <Rony.Flatscher at wu.ac.at> wrote:

Hi.

> The road to hell is paved with good intentions ... 

Every Java library requires adding a token to the command line; what we’re talking about here is adding another one for the small minority of libraries that use native code. 

In fact, the command line work that’s required has barely changed. If you’re using the classpath, then most applications typically mention each and every JAR individually; if any of them requires native access you only need to add --enable-native-access=ALL-UNNAMED. If, on the other hand, you’re using the module path, then normally you’re only providing a single directory, and now you’ll also have to list every module that requires native access, and it’s still *fewer* tokens on the command line than Java applications put there ten years ago.

So we can talk about the merits of this minor inconvenience, but merited or not — it’s not something that can lead to any hell.

> A few minor thoughts:
>     • Java needs JNI itself: so how can the "user" be warned from using Java as this is considered to be potentially dangerous by the Java developers themselves? 
> (And what can be done to warn a "user" from using operating system features? Should Java warn the "user" that potentially dangerous native code gets employed by Java whenever the operating system gets accessed for one reason or another?)

I’m afraid there’s been some confusion about who the user is. The user we’re referring to in the JEP is the application author. The application’s end user need not add any flags, see any flags, or even be aware they’re running an application written in Java. All the flags we’re discussing are internal to the application, and can be collected in the usual way in configuration @files or with jlink. The application’s author has a choice of whether or not to use a library that requires certain special powers, in this case — running native code.

The application’s author chooses what launcher to use, and that launcher can grant native access privileges to any library that the application author chooses. If someone uses the launcher that comes with the JDK it is preconfigured with such permissions for the JDK’s modules.

> 
>     • Possible dangerous or fatal errors in native code do not mean that these errors exist in reality at all, i.e. in deployed JNI modules that get tested and deployed. 
> This is a bit along the line that a knife can be dangerous as it can be used to kill a person, yet, knives in the world do not get used to kill people: the good intent is to make the world safer, so we prohibit knives or only allow their use, if the user keys in the flag "--knives-can-kill-persons" and then the storage box opens to release the knife such that one can finally cut the steak. 
> (Just because something can be used dangerously does not mean that it will be used that way and do harm; any acknowledgement of potential danger does not make the danger go away nor does the warning help to circumvent the potential danger.)

Sure, which is why we’re not discouraging the use of native code, just asking the application’s author to acknowledge that they know there are knives in play.

> 
>     • Just pointing out that erroneously implemented JNI modules can be harmful is enough and has been evident since JNI exists, so what has changed all of a sudden? 

The linked JEP explains that in the “Why Now” section. In short: because the JDK is now changing faster than it ever did before, because more and more of it is being written in Java, and because the security threat landscape has changed.

> 
>     • Deployment of Java: there seems to be the wrong assumption among some developers that Java is not being used as a JRE (non-JRE bubble?) which is simply wrong. What should applications do in a scenario in which the JVM gets dynamically loaded via JNI to then interact with the JRE? Is that considered to be dangerous such that it needs to be made seen by the "user" each time this demand loading of the JVM happens as otherwise the "user" does not realize that theoretically a potential danger exists (and if so for whom)? 

I’m not sure what you mean by JRE (the JRE is something that no longer exists), but the JEP addresses the use of the invocation API. Obviously, whatever launcher is used is controlled by the application author, who can decide who can do what. 

> 
>     • Who is really the "user" who gets addressed here? (How stupid is this particular "user" regarded to be?)

The application author. The assumption is that they’ve somehow assembled a dependency graph and may not be aware whether any of the transitive dependencies have superpowers that may override the integrity guarantee that we’d like the JDK to make by default.

> 
>     • Why is it not enough to simply record the fact that JNI gets employed explicitly in module-info? As has been mentioned a few times this would allow for appropriate analysis, if need be? (It also might suffice the intentions of the JEP in that the warnings get issued only if the fact that JNI gets employed in a module is not reported in its module-info.)

Because, as the linked JEP explains (https://openjdk.org/jeps/8305968) the goal is to gain the permission of the application’s author. A library cannot decide grant itself superpowers that could change any of the integrity guarantees made by the JDK. The application has to grant that permission to the library.

— Ron


More information about the jdk-dev mailing list