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

URLClassLoader may check that a JAR file starts with a local file header

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P3 P3
    • 24
    • core-libs
    • None
    • behavioral
    • minimal
    • Hide
      The change here is documenting a previously unspecified "sun.misc.URLClassPath.disableJarChecking" system property. Existing applications that were launching with this property set to "true" or an empty value, with an intention to disable the JAR check will continue to behave the same. As such, this change isn't expected to cause a compatibility impact.
      Show
      The change here is documenting a previously unspecified "sun.misc.URLClassPath.disableJarChecking" system property. Existing applications that were launching with this property set to "true" or an empty value, with an intention to disable the JAR check will continue to behave the same. As such, this change isn't expected to cause a compatibility impact.
    • System or security property
    • JDK

      Summary

      When enabled through a system property, the java.net.URLClassLoader will check that the byte content of the JAR file, corresponding to a classpath element, starts with the local file header as specified by the ZIP file format specification.

      Problem

      A URLClassLoader can be constructed to load resources from a classpath. Each of the classpath elements is a java.net.URL instance. In the most common form, the classpath elements are either a directory on the file system or a JAR file. When locating resources in the classpath, the URLClassLoader does the necessary processing of these classpath elements. For a JAR file, the URLClassLoader, through the java.util.jar.JarFile API, parses the JAR file contents and uses that JarFile instance to locate resources within that JAR file.

      A JAR file is based on the ZIP file format (https://pkwaredownloads.blob.core.windows.net/pem/APPNOTE.txt). One important detail about the ZIP file format is that, the metadata of the contents in the ZIP file is maintained in a central directory and the central directory itself is present towards the end of the ZIP file contents. The central directory contains the offset (within the byte stream) of individual entries of the ZIP file.

      Given this arrangement, it's possible and even allowed by the ZIP specification, that given a byte stream of N bytes, the first few X bytes may be some arbitrary content that doesn't represent the ZIP file format and the rest N - X bytes could represent valid ZIP file format content. Various tools are capable of parsing such content into a ZIP file. The JarFile API in the JDK too is capable of successfully parsing that byte stream of N bytes into a JarFile that represents only the N - X bytes. Such JarFile instances are seamlessly constructed and used within the Java runtime.

      In the presence of a java.lang.SecurityManager, the internal implementation of the URLClassLoader used to perform a check to verify that the JarFile constructed out of a byte stream, corresponding to a classpath element, did not infact contain these additional arbitrary bytes at the beginning of the byte stream. To do so, it used to verify that the first 4 bytes of the byte stream represented a local file header (0x04034b50) as specified by the ZIP file format specification. A JarFile, constructed out of a URL corresponding to the classpath element, would not be considered for resource loading if it failed that check. This check was only done in the presence of a SecurityManager and if the sun.misc.URLClassPath.disableJarChecking system property wasn't set to true. The sun.misc.URLClassPath.disableJarChecking was an unspecified system property which applications could set to true to disable this check even in the presence of the SecurityManager. Although unspecified, this system property has seen usage in external applications where certain launch scripts configure this property with a value true to explicitly disable this JAR file check.

      With the SecurityManager implementation now removed through JEP 486, the URLClassLoader needs to decide whether to continue supporting this check.

      Solution

      The URLClassLoader will continue to do this JAR file check only if the runtime was launched with the sun.misc.URLClassPath.disableJarChecking system property set to false. A value of false will imply that this JAR file check is enabled by the application. Absence of this system property or any other value for this system property will disable this JAR file check. SecurityManager APIs will no longer play any role in this check.

      Existing applications which were launching the runtime with -Dsun.misc.URLClassPath.disableJarChecking=true with an intention of disabling the check, would thus continue to function like before.

      An alternative of discontinuing this check in the URLClassLoader, irrespective of whether or not this system property was set to some value, was considered. However, it was felt that it might be good to continue with this check (when explicitly enabled) until the time where some tool (preferably the jar tool), at build or deployment time, could help identify JAR files that do not start with a ZIP local file header.

      Specification

      Not applicable.

            jpai Jaikiran Pai
            dfuchs Daniel Fuchs
            Daniel Fuchs
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: