Skip to content
  • Nick Wellnhofer's avatar
    Fix handling of parameter-entity references · e2663054
    Nick Wellnhofer authored
    There were two bugs where parameter-entity references could lead to an
    unexpected change of the input buffer in xmlParseNameComplex and
    xmlDictLookup being called with an invalid pointer.
    
    Percent sign in DTD Names
    =========================
    
    The NEXTL macro used to call xmlParserHandlePEReference. When parsing
    "complex" names inside the DTD, this could result in entity expansion
    which created a new input buffer. The fix is to simply remove the call
    to xmlParserHandlePEReference from the NEXTL macro. This is safe because
    no users of the macro require expansion of parameter entities.
    
    - xmlParseNameComplex
    - xmlParseNCNameComplex
    - xmlParseNmtoken
    
    The percent sign is not allowed in names, which are grammatical tokens.
    
    - xmlParseEntityValue
    
    Parameter-entity references in entity values are expanded but this
    happens in a separate step in this function.
    
    - xmlParseSystemLiteral
    
    Parameter-entity references are ignored in the system literal.
    
    - xmlParseAttValueComplex
    - xmlParseCharDataComplex
    - xmlParseCommentComplex
    - xmlParsePI
    - xmlParseCDSect
    
    Parameter-entity references are ignored outside the DTD.
    
    - xmlLoadEntityContent
    
    This function is only called from xmlStringLenDecodeEntities and
    entities are replaced in a separate step immediately after the function
    call.
    
    This bug could also be triggered with an internal subset and double
    entity expansion.
    
    This fixes bug 766956 initially reported by Wei Lei and independently by
    Chromium's ClusterFuzz, Hanno Böck, and Marco Grassi. Thanks to everyone
    involved.
    
    xmlParseNameComplex with XML_PARSE_OLD10
    ========================================
    
    When parsing Names inside an expanded parameter entity with the
    XML_PARSE_OLD10 option, xmlParseNameComplex would call xmlGROW via the
    GROW macro if the input buffer was exhausted. At the end of the
    parameter entity's replacement text, this function would then call
    xmlPopInput which invalidated the input buffer.
    
    There should be no need to invoke GROW in this situation because the
    buffer is grown periodically every XML_PARSER_CHUNK_SIZE characters and,
    at least for UTF-8, in xmlCurrentChar. This also matches the code path
    executed when XML_PARSE_OLD10 is not set.
    
    This fixes bugs 781205 (CVE-2017-9049) and 781361 (CVE-2017-9050).
    Thanks to Marcel Böhme and Thuan Pham for the report.
    
    Additional hardening
    ====================
    
    A separate check was added in xmlParseNameComplex to validate the
    buffer size.
    e2663054