Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8297684

NullPointerException in JarVerifier prevents JVM from starting

    XMLWordPrintable

Details

    • b01
    • generic
    • generic

    Description

      ADDITIONAL SYSTEM INFORMATION :
      openjdk 17.0.5 2022-10-18
      OpenJDK Runtime Environment Temurin-17.0.5+8 (build 17.0.5+8)
      OpenJDK 64-Bit Server VM Temurin-17.0.5+8 (build 17.0.5+8, mixed mode, sharing)

      JVM started with -Djava.locale.providers=COMPAT,SPI.


      A DESCRIPTION OF THE PROBLEM :
      After upgrading from Java 17.0.4+8 to 17.0.5+8 JVM refused to start due to an exception in the JAR verification process. The issue is probably related to https://bugs.openjdk.org/browse/JDK-8269039 which disabled SHA-1 signed JARs. As far as I can tell no SHA-1 signed JARs where on the class path.

      The reason for the NullPointerException is a design flaw in the sun.security.pkcs.SignerInfo class which permits code paths that use this itself class during its initialization.

      In our case the initialization of

      private static final DisabledAlgorithmConstraints JAR_DISABLED_CHECK =
                  DisabledAlgorithmConstraints.jarConstraints();

      https://github.com/openjdk/jdk/blob/76a24c3f90d8e0655bfcaa3dd5c2d1f74515ebc6/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java#L49

      leads to a call to the verifyAlgorithms method which in turn tries to use the static JAR_DISABLED_CHECK class member:

      https://github.com/openjdk/jdk/blob/76a24c3f90d8e0655bfcaa3dd5c2d1f74515ebc6/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java#L740

      since this field is not yet initialized a NullPointerException occurs which leads to an ExceptionInInitializerError.

      Exception in thread "main" java.lang.ExceptionInInitializerError
      at java.base/sun.security.util.DisabledAlgorithmConstraints.jarConstraints(DisabledAlgorithmConstraints.java:112)
      at java.base/un.security.pkcs.SignerInfos.<clinit>(SignerInfo.java:61)
      at java.base/sun.security.pkcs.PKCS7.parseSignedData(PKCS7.java:380)
      at java.base/sun.security.pkcs.PKCS7.parse(PKCS7.java:174)
      at java.base/sun.security.pkcs.PKCS7.parse(PKCS7.java:142)
      at java.base/sun.security.pkcs.PKCS7.<init>(PKCS7.java:124)
      at java.base/sun.security.util.SignatureFileVerifier.<init>(SignatureFileVerifier.java:118)
      at java.base/java.util.jar.JarVerifier.processEntry(JarVerifier.java:308)
      at java.base/java.util.jar.JarVerifier.update(JarVerifier.java:239)
      at java.base/java.util.jar.JarFile.initializeVerifier(JarFile.java:762)
      at java.base/java.util.jar.JarFile.getInputStream(JarFile.java:845)
      at java.base/jdk.internal.util.jar.JarIndex.getJarIndex(JarIndex.java:121)
      at java.base/jdk.internal.loader.URLClassPath$JarLoader$1.run(URLClassPath.java:770)
      at java.base/jdk.internal.loader.URLClassPath$JarLoader$1.run(URLClassPath.java:762)
      at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
      at java.base/jdk.internal.loader.URLClassPath$JarLoader.ensureOpen(URLClassPath.java:761)
      at java.base/jdk.internal.loader.URLClassPath$JarLoader.<init>(URLClassPath.java:735)
      at java.base/jdk.internal.loader.URLClassPath$3.run(URLClassPath.java:499)
      at java.base/jdk.internal.loader.URLClassPath$3.run(URLClassPath.java:482)
      at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
      at java.base/jdk.internal.loader.URLClassPath.getLoader(URLClassPath.java:481)
      at java.base/jdk.internal.loader.URLClassPath.getLoader(URLClassPath.java:449)
      at java.base/jdk.internal.loader.URLClassPath$1.next(URLClassPath.java:345)
      at java.base/jdk.internal.loader.URLClassPath$1.hasMoreElements(URLClassPath.java:356)
      at java.base/jdk.internal.loader.BuiltinClassLoader$1.hasNext(BuiltinClassLoader.java:408)
      at java.base/jdk.internal.loader.BuiltinClassLoader$1.hasMoreElements(BuiltinClassLoader.java:416)
      at java.base/java.lang.CompoundEnumeration.next(ClassLoader.java:2725)
      at java.base/java.lang.CompoundEnumeration.hasMoreElements(ClassLoader.java:2734)
      at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.nextProviderClass(ServiceLoader.java:1210)
      at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNextService(ServiceLoader.java:1228)
      at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNext(ServiceLoader.java:1273)
      at java.base/java.util.ServiceLoader$2.hasNext(ServiceLoader.java:1309)
      at java.base/java.util.ServiceLoader$3.hasNext(ServiceLoader.java:1393)
      at java.base/jdk.internal.logger.BootstrapLogger$DetectBackend$1.run(BootstrapLogger.java:897)
      at java.base/jdk.internal.logger.BootstrapLogger$DetectBackend$1.run(BootstrapLogger.java:891)
      at java.base/java.security.AccessController.doPrivileged(AccessController.java:318)
      at java.base/jdk.internal.logger.BootstrapLogger$DetectBackend.<clinit>(BootstrapLogger.java:891)
      at java.base/jdk.internal.logger.BootstrapLogger.useLazyLoggers(BootstrapLogger.java:939)
      at java.base/jdk.internal.logger.LazyLoggers.getLazyLogger(LazyLoggers.java:441)
      at java.base/jdk.internal.logger.LazyLoggers.getLogger(LazyLoggers.java:416)
      at java.base/java.lang.System.getLogger(System.java:1769)
      at java.base/jdk.internal.event.EventHelper.isLoggingSecurity(EventHelper.java:148)
      at java.base/sun.security.provider.X509Factory.commitEvent(X509Factory.java:773)
      at java.base/sun.security.provider.X509Factory.engineGenerateCertificate(X509Factory.java:108)
      at java.base/java.security.cert.CertificateFactory.generateCertificate(CertificateFactory.java:355)
      at java.base/sun.security.pkcs.PKCS7.parseSignedData(PKCS7.java:317)
      at java.base/sun.security.pkcs.PKCS7.parse(PKCS7.java:174)
      at java.base/sun.security.pkcs.PKCS7.parse(PKCS7.java:142)
      at java.base/sun.security.pkcs.PKCS7.<init>(PKCS7.java:124)
      at java.base/sun.security.util.SignatureFileVerifier.<init>(SignatureFileVerifier.java:118)
      at java.base/java.util.jar.JarVerifier.processEntry(JarVerifier.java:308)
      at java.base/java.util.jar.JarVerifier.update(JarVerifier.java:239)
      at java.base/java.util.jar.JarFile.initializeVerifier(JarFile.java:762)
      at java.base/java.util.jar.JarFile.getInputStream(JarFile.java:845)
      at java.base/jdk.internal.util.jar.JarIndex.getJarIndex(JarIndex.java:121)
      at java.base/jdk.internal.loader.URLClassPath$JarLoader$1.run(URLClassPath.java:770)
      at java.base/jdk.internal.loader.URLClassPath$JarLoader$1.run(URLClassPath.java:762)
      at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
      at java.base/jdk.internal.loader.URLClassPath$JarLoader.ensureOpen(URLClassPath.java:761)
      at java.base/jdk.internal.loader.URLClassPath$JarLoader.<init>(URLClassPath.java:735)
      at java.base/jdk.internal.loader.URLClassPath$3.run(URLClassPath.java:499)
      at java.base/jdk.internal.loader.URLClassPath$3.run(URLClassPath.java:482)
      at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
      at java.base/jdk.internal.loader.URLClassPath.getLoader(URLClassPath.java:481)
      at java.base/jdk.internal.loader.URLClassPath.getLoader(URLClassPath.java:449)
      at java.base/jdk.internal.loader.URLClassPath$1.next(URLClassPath.java:345)
      at java.base/jdk.internal.loader.URLClassPath$1.hasMoreElements(URLClassPath.java:356)
      at java.base/jdk.internal.loader.BuiltinClassLoader$1.hasNext(BuiltinClassLoader.java:408)
      at java.base/jdk.internal.loader.BuiltinClassLoader$1.hasMoreElements(BuiltinClassLoader.java:416)
      at java.base/java.lang.CompoundEnumeration.next(ClassLoader.java:2725)
      at java.base/java.lang.CompoundEnumeration.hasMoreElements(ClassLoader.java:2734)
      at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.nextProviderClass(ServiceLoader.java:1210)
      at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNextService(ServiceLoader.java:1228)
      at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNext(ServiceLoader.java:1273)
      at java.base/java.util.ServiceLoader$2.hasNext(ServiceLoader.java:1309)
      at java.base/java.util.ServiceLoader$3.hasNext(ServiceLoader.java:1393)
      at org.slf4j.LoggerFactory.findServiceProviders(LoggerFactory.java:104)
      at org.slf4j.LoggerFactory.bind(LoggerFactory.java:147)
      at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:139)
      at org.slf4j.LoggerFactory.getProvider(LoggerFactory.java:422)
      at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:408)
      at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:357)
      at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:383)
      at de.uplanet.lucy.server.portalserver.PortalService.<clinit>(PortalService.java:84)
      Caused by: java.lang.NullPointerException: Cannot invoke "sun.security.util.DisabledAlgorithmConstraints.permits(String, java.security.AlgorithmParameters, sun.security.util.ConstraintsParameters, boolean)" because "sun.security.pkcs.SignerInfo.JAR_DISABLED_CHECK" is null
      at java.base/sun.security.pkcs.SignerInfo.verifyAlgorithms(SignerInfo.java:761)
      at java.base/sun.security.util.SignatureFileVerifier.processImpl(SignatureFileVerifier.java:324)
      at java.base/sun.security.util.SignatureFileVerifier.process(SignatureFileVerifier.java:282)
      at java.base/java.util.jar.JarVerifier.processEntry(JarVerifier.java:327)
      at java.base/java.util.jar.JarVerifier.update(JarVerifier.java:239)
      at java.base/java.util.jar.JarFile.initializeVerifier(JarFile.java:762)
      at java.base/java.util.jar.JarFile.getInputStream(JarFile.java:845)
      at java.base/jdk.internal.util.jar.JarIndex.getJarIndex(JarIndex.java:121)
      at java.base/jdk.internal.loader.URLClassPath$JarLoader$1.run(URLClassPath.java:770)
      at java.base/jdk.internal.loader.URLClassPath$JarLoader$1.run(URLClassPath.java:762)
      at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
      at java.base/jdk.internal.loader.URLClassPath$JarLoader.ensureOpen(URLClassPath.java:761)
      at java.base/jdk.internal.loader.URLClassPath$JarLoader.<init>(URLClassPath.java:735)
      at java.base/jdk.internal.loader.URLClassPath$3.run(URLClassPath.java:499)
      at java.base/jdk.internal.loader.URLClassPath$3.run(URLClassPath.java:482)
      at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
      at java.base/jdk.internal.loader.URLClassPath.getLoader(URLClassPath.java:481)
      at java.base/jdk.internal.loader.URLClassPath.getLoader(URLClassPath.java:449)
      at java.base/jdk.internal.loader.URLClassPath$1.next(URLClassPath.java:345)
      at java.base/jdk.internal.loader.URLClassPath$1.hasMoreElements(URLClassPath.java:356)
      at java.base/jdk.internal.loader.BuiltinClassLoader$1.hasNext(BuiltinClassLoader.java:408)
      at java.base/jdk.internal.loader.BuiltinClassLoader$1.hasMoreElements(BuiltinClassLoader.java:416)
      at java.base/java.lang.CompoundEnumeration.next(ClassLoader.java:2725)
      at java.base/java.lang.CompoundEnumeration.hasMoreElements(ClassLoader.java:2734)
      at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.nextProviderClass(ServiceLoader.java:1210)
      at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNextService(ServiceLoader.java:1228)
      at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNext(ServiceLoader.java:1273)
      at java.base/java.util.ServiceLoader$2.hasNext(ServiceLoader.java:1309)
      at java.base/java.util.ServiceLoader$3.hasNext(ServiceLoader.java:1393)
      at java.base/sun.util.locale.provider.SPILocaleProviderAdapter$1.run(SPILocaleProviderAdapter.java:83)
      at java.base/sun.util.locale.provider.SPILocaleProviderAdapter$1.run(SPILocaleProviderAdapter.java:76)
      at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
      at java.base/sun.util.locale.provider.SPILocaleProviderAdapter.findInstalledProvider(SPILocaleProviderAdapter.java:76)
      at java.base/sun.util.locale.provider.AuxLocaleProviderAdapter.getLocaleServiceProvider(AuxLocaleProviderAdapter.java:73)
      at java.base/sun.util.locale.provider.LocaleServiceProviderPool.findProviders(LocaleServiceProviderPool.java:304)
      at java.base/sun.util.locale.provider.LocaleServiceProviderPool.getLocalizedObjectImpl(LocaleServiceProviderPool.java:274)
      at java.base/sun.util.locale.provider.LocaleServiceProviderPool.getLocalizedObject(LocaleServiceProviderPool.java:256)
      at java.base/sun.util.locale.provider.CalendarDataUtility.retrieveFirstDayOfWeek(CalendarDataUtility.java:76)
      at java.base/java.util.Calendar.setWeekCountData(Calendar.java:3397)
      at java.base/java.util.Calendar.<init>(Calendar.java:1607)
      at java.base/java.util.GregorianCalendar.<init>(GregorianCalendar.java:738)
      at java.base/java.util.Calendar$Builder.build(Calendar.java:1492)
      at java.base/sun.security.util.DisabledAlgorithmConstraints$DenyAfterConstraint.<init>(DisabledAlgorithmConstraints.java:716)
      at java.base/sun.security.util.DisabledAlgorithmConstraints$Constraints.<init>(DisabledAlgorithmConstraints.java:428)
      at java.base/sun.security.util.DisabledAlgorithmConstraints.<init>(DisabledAlgorithmConstraints.java:148)
      at java.base/sun.security.util.DisabledAlgorithmConstraints.<init>(DisabledAlgorithmConstraints.java:122)
      at java.base/sun.security.util.DisabledAlgorithmConstraints$JarHolder.<clinit>(DisabledAlgorithmConstraints.java:98)
      ... 84 more

      REGRESSION : Last worked in version 17

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      We have tried to find a minimal reproducible example that shows the issue, but unfortunately did not succeed.

      However, the provided stack trace clearly shows that there are code paths that cause the class initializer to call itself in the uninitialized state which leads to the NPE.


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      JVM should not crash during startup.
      ACTUAL -
      JVM crashes due to a NPE during the initialization of the sun.security.pkcs.SignerInfo class.

      CUSTOMER SUBMITTED WORKAROUND :
      1.) The problem disappears when SHA-1 is removed from jdk.jar.disabledAlgorithms in conf/security/java.security. Note that none of the JARs involved was signed using SHA-1.

      2.) Replacing -Djava.locale.providers=COMPAT,SPI with -Djava.locale.providers=COMPAT avoids the NPE in this special case. But there may be other circumstances under which the bug may appear without SPI being set.


      FREQUENCY : always


      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: