oracle / graal

GraalVM compiles Java applications into native executables that start instantly, scale fast, and use fewer compute resources 🚀
https://www.graalvm.org
Other
20.45k stars 1.64k forks source link

[GR-46809] NPE when removing Java Security Providers from java.security file located in JDK #6797

Open SergejIsbrecht opened 1 year ago

SergejIsbrecht commented 1 year ago

Describe the issue Trying to build a native-image with disabled Java Security Providers by commenting out security providers in ./conf/security/java.security

Steps to reproduce the issue

  1. Checkout https://github.com/SergejIsbrecht/graalvm_SecurityServicesFeature_NPE
  2. follow README.md instructions in repository

Describe GraalVM and your environment:

More details

When trying to build a native-image with java.security

...
security.provider.1=SUN
# security.provider.2=SunRsaSign
# security.provider.3=SunEC
# security.provider.4=SunJSSE
# security.provider.5=SunJCE
# security.provider.6=SunJGSS
# security.provider.7=SunSASL
# security.provider.8=XMLDSig
# security.provider.9=SunPCSC
# security.provider.10=JdkLDAP
# security.provider.11=JdkSASL
# security.provider.12=SunPKCS11
...

following Exception is being thrown during native-image generation

Fatal error: java.lang.NullPointerException: Cannot invoke "java.util.Set.iterator()" because "services" is null
        at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.SecurityServicesFeature.doRegisterServices(SecurityServicesFeature.java:575)
        at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.SecurityServicesFeature.lambda$registerServices$9(SecurityServicesFeature.java:566)
        at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)
        at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.SecurityServicesFeature.registerServices(SecurityServicesFeature.java:565)
        at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.SecurityServicesFeature.registerServices(SecurityServicesFeature.java:544)
        at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.SecurityServicesFeature.lambda$registerServiceReachabilityHandlers$6(SecurityServicesFeature.java:509)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.meta.AnalysisElement$MethodOverrideReachableNotification.lambda$notifyCallback$0(AnalysisElement.java:206)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.meta.AnalysisElement.lambda$execute$1(AnalysisElement.java:219)
    at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.CompletionExecutor.executeCommand(CompletionExecutor.java:187)
------------------------------------------------------------------------------------------------------------------------
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.CompletionExecutor.lambda$executeService$0(CompletionExecutor.java:171)
        at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1395)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
        at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)
                        0.4s (4.0% of total time) in 39 GCs | Peak RSS: 0.73GB | CPU load: 8.25
========================================================================================================================
Finished generating 'application' in 9.2s.
com.oracle.svm.driver.NativeImage$NativeImageError
        at org.graalvm.nativeimage.driver/com.oracle.svm.driver.NativeImage.showError(NativeImage.java:2019)
        at org.graalvm.nativeimage.driver/com.oracle.svm.driver.NativeImage.build(NativeImage.java:1641)
        at org.graalvm.nativeimage.driver/com.oracle.svm.driver.NativeImage.performBuild(NativeImage.java:1600)
        at org.graalvm.nativeimage.driver/com.oracle.svm.driver.NativeImage.main(NativeImage.java:1574)

I would expect either a proper error message or no NPE at all. It is not visible which provider is NOT found.

SecurityServicesFeature.java

    @SuppressWarnings("try")
    private void doRegisterServices(DuringAnalysisAccess access, Object trigger, String serviceType) {
        try (TracingAutoCloseable ignored = trace(access, trigger, serviceType)) {
            Set<Service> services = availableServices.get(serviceType);
            for (Service service : services) {
                registerService(access, service);
            }
        }
    }

It seems availableServices.get(serviceType) is null.

Resolution

This seems to be the minimal setup to not cause a NPE with conscrypt JSP being available.

java.security

security.provider.1=SUN
security.provider.2=SunRsaSign
security.provider.3=SunEC
security.provider.4=SunJSSE
security.provider.5=SunJCE
SergejIsbrecht commented 1 year ago

/cc @cstancu

oubidar-Abderrahim commented 1 year ago

Tracked internally on GR 46809

cstancu commented 1 year ago

@SergejIsbrecht yes, it seems that availableServices.get(serviceType) is null, although not clear for which service type. This makes sense since availableServices are collected based on the result of Security.getProviders() and some providers are now missing. The serviceType argument comes from a reachability handler, so the code for the specific provider that is missing and that declares that service type is still reachable. The proper fix would be to add a null check and and a comment:

            if (services != null) {
                /*
                 * The availableServices depend on Security.getProviders(), i.e., on which providers
                 * are configured in the java.security file. Consequently services for specific
                 * services types may be missing.
                 */
                for (Service service : services) {
                    registerService(access, service);
                }
            }
        }

Please let me know if this fixes your issue and if so feel free to open a PR.