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

Initialization race in com.sun.org.apache.xerces.internal.impl.xpath.regex.Token.getRange() on Token.categories

XMLWordPrintable

    • b15
    • x86_64
    • linux

        FULL PRODUCT VERSION :
        openjdk version "1.8.0_144"
        OpenJDK Runtime Environment (Zulu 8.23.0.3-linux64) (build 1.8.0_144-b01)
        OpenJDK 64-Bit Server VM (Zulu 8.23.0.3-linux64) (build 25.144-b01, mixed mode)

        The code in question doesn't seem to have materially changed as of 9.0.4 but I haven't yet run the repro there.

        ADDITIONAL OS VERSION INFORMATION :
        Linux amling 3.2.0-38-generic #61-Ubuntu SMP Tue Feb 19 12:18:21 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

        A DESCRIPTION OF THE PROBLEM :
        The attempts of this code to guard initialization of Token.categories are flawed. On an appropriate race one thread can see partially initialized values and therefore fail a lookup of a legal key.

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        I actually think the getRange code pretty much speaks for itself, but I have attached demo code but since separate attempts to proc this take new JVMs it takes a long time (~3h, ~16K runs) to reproduce for me.

        In production we have seen this due to concurrent jasper compiles in the same JVM, essentially via javax.xml.parsers.DocumentBuilderFactory parsing some document with a pattern in it. The attached demo shortcuts most of this and calls on RegularExpression directly to try to make the race proc more often.

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        Demo passes 100% of the time.
        ACTUAL -
        Demo passed estimated 99.994% of the time.

        ERROR MESSAGES/STACK TRACES THAT OCCUR :
        org.xml.sax.SAXParseException; systemId: jar:file:<path>/jboss-servlet-api_3.1_spec/1.0.0.Final/jboss-servlet-api_3.1_spec-1.0.0.Final.jar!/javax/servlet/resources/web-common_3_0.xsd; lineNumber: 601; columnNumber: 39; InvalidRegex: Pattern value '[!-~-[\(\)<>@,;:"/\[\]?=\{\}\\\p{Z}]]+' is not a valid regular expression. The reported error was: 'Unknown property.' at column '{2}'.
        at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203)
        at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:134)
        at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:396)
        at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaErr(XSDHandler.java:4154)
        at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaError(XSDHandler.java:4137)
        at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDAbstractTraverser.reportSchemaError(XSDAbstractTraverser.java:721)
        at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDSimpleTypeTraverser.getSimpleType(XSDSimpleTypeTraverser.java:406)
        at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDSimpleTypeTraverser.traverseSimpleTypeDecl(XSDSimpleTypeTraverser.java:163)
        at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDSimpleTypeTraverser.traverseGlobal(XSDSimpleTypeTraverser.java:104)
        at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.traverseSchemas(XSDHandler.java:1448)
        at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.parseSchema(XSDHandler.java:635)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadSchema(XMLSchemaLoader.java:610)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.findSchemaGrammar(XMLSchemaValidator.java:2447)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleStartElement(XMLSchemaValidator.java:1768)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.startElement(XMLSchemaValidator.java:741)
        at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:374)
        at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:613)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3132)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:852)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602)
        at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:112)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:505)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:842)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:771)
        at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
        at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:243)
        at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:339)
        at org.apache.jasper.xmlparser.ParserUtils.parseXMLDocument(ParserUtils.java:133)
        ... 48 more


        REPRODUCIBILITY :
        This bug can be reproduced occasionally.

        ---------- BEGIN SOURCE ----------
        import java.util.concurrent.CountDownLatch;

        public class Demo {
            private static volatile boolean broken = false;

            public static void main(String[] args) throws Exception {
                int N = 10;

                CountDownLatch cdl = new CountDownLatch(N);
                Thread[] t = new Thread[N];
                for(int i = 0; i < N; ++i) {
                    t[i] = new Thread() {
                        @Override
                        public void run() {
                            cdl.countDown();
                            try {
                                cdl.await();
                                new com.sun.org.apache.xerces.internal.impl.xpath.regex.RegularExpression("[\\p{Z}]", "X", java.util.Locale.US);
                            }
                            catch(Exception e) {
                                e.printStackTrace();
                                broken = true;
                            }
                        }
                    };
                    t[i].start();
                }
                for(int i = 0; i < N; ++i) {
                    t[i].join();
                }
                if(broken) {
                    System.exit(1);
                }
            }
        }

        ---------- END SOURCE ----------

              joehw Joe Wang
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

                Created:
                Updated:
                Resolved: