0005-Fix-XPointer-paths-beginning-with-range-to.patch 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. From 9ab01a277d71f54d3143c2cf333c5c2e9aaedd9e Mon Sep 17 00:00:00 2001
  2. From: Nick Wellnhofer <wellnhofer@aevum.de>
  3. Date: Tue, 28 Jun 2016 14:22:23 +0200
  4. Subject: [PATCH] Fix XPointer paths beginning with range-to
  5. The old code would invoke the broken xmlXPtrRangeToFunction. range-to
  6. isn't really a function but a special kind of location step. Remove
  7. this function and always handle range-to in the XPath code.
  8. The old xmlXPtrRangeToFunction could also be abused to trigger a
  9. use-after-free error with the potential for remote code execution.
  10. Found with afl-fuzz.
  11. Fixes CVE-2016-5131.
  12. ---
  13. result/XPath/xptr/vidbase | 13 ++++++++
  14. test/XPath/xptr/vidbase | 1 +
  15. xpath.c | 7 ++++-
  16. xpointer.c | 76 ++++-------------------------------------------
  17. 4 files changed, 26 insertions(+), 71 deletions(-)
  18. --- a/xpath.c
  19. +++ b/xpath.c
  20. @@ -10691,13 +10691,18 @@ xmlXPathCompPathExpr(xmlXPathParserConte
  21. lc = 1;
  22. break;
  23. } else if ((NXT(len) == '(')) {
  24. - /* Note Type or Function */
  25. + /* Node Type or Function */
  26. if (xmlXPathIsNodeType(name)) {
  27. #ifdef DEBUG_STEP
  28. xmlGenericError(xmlGenericErrorContext,
  29. "PathExpr: Type search\n");
  30. #endif
  31. lc = 1;
  32. +#ifdef LIBXML_XPTR_ENABLED
  33. + } else if (ctxt->xptr &&
  34. + xmlStrEqual(name, BAD_CAST "range-to")) {
  35. + lc = 1;
  36. +#endif
  37. } else {
  38. #ifdef DEBUG_STEP
  39. xmlGenericError(xmlGenericErrorContext,
  40. --- a/xpointer.c
  41. +++ b/xpointer.c
  42. @@ -1332,8 +1332,6 @@ xmlXPtrNewContext(xmlDocPtr doc, xmlNode
  43. ret->here = here;
  44. ret->origin = origin;
  45. - xmlXPathRegisterFunc(ret, (xmlChar *)"range-to",
  46. - xmlXPtrRangeToFunction);
  47. xmlXPathRegisterFunc(ret, (xmlChar *)"range",
  48. xmlXPtrRangeFunction);
  49. xmlXPathRegisterFunc(ret, (xmlChar *)"range-inside",
  50. @@ -2243,76 +2241,14 @@ xmlXPtrRangeInsideFunction(xmlXPathParse
  51. * @nargs: the number of args
  52. *
  53. * Implement the range-to() XPointer function
  54. + *
  55. + * Obsolete. range-to is not a real function but a special type of location
  56. + * step which is handled in xpath.c.
  57. */
  58. void
  59. -xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt, int nargs) {
  60. - xmlXPathObjectPtr range;
  61. - const xmlChar *cur;
  62. - xmlXPathObjectPtr res, obj;
  63. - xmlXPathObjectPtr tmp;
  64. - xmlLocationSetPtr newset = NULL;
  65. - xmlNodeSetPtr oldset;
  66. - int i;
  67. -
  68. - if (ctxt == NULL) return;
  69. - CHECK_ARITY(1);
  70. - /*
  71. - * Save the expression pointer since we will have to evaluate
  72. - * it multiple times. Initialize the new set.
  73. - */
  74. - CHECK_TYPE(XPATH_NODESET);
  75. - obj = valuePop(ctxt);
  76. - oldset = obj->nodesetval;
  77. - ctxt->context->node = NULL;
  78. -
  79. - cur = ctxt->cur;
  80. - newset = xmlXPtrLocationSetCreate(NULL);
  81. -
  82. - for (i = 0; i < oldset->nodeNr; i++) {
  83. - ctxt->cur = cur;
  84. -
  85. - /*
  86. - * Run the evaluation with a node list made of a single item
  87. - * in the nodeset.
  88. - */
  89. - ctxt->context->node = oldset->nodeTab[i];
  90. - tmp = xmlXPathNewNodeSet(ctxt->context->node);
  91. - valuePush(ctxt, tmp);
  92. -
  93. - xmlXPathEvalExpr(ctxt);
  94. - CHECK_ERROR;
  95. -
  96. - /*
  97. - * The result of the evaluation need to be tested to
  98. - * decided whether the filter succeeded or not
  99. - */
  100. - res = valuePop(ctxt);
  101. - range = xmlXPtrNewRangeNodeObject(oldset->nodeTab[i], res);
  102. - if (range != NULL) {
  103. - xmlXPtrLocationSetAdd(newset, range);
  104. - }
  105. -
  106. - /*
  107. - * Cleanup
  108. - */
  109. - if (res != NULL)
  110. - xmlXPathFreeObject(res);
  111. - if (ctxt->value == tmp) {
  112. - res = valuePop(ctxt);
  113. - xmlXPathFreeObject(res);
  114. - }
  115. -
  116. - ctxt->context->node = NULL;
  117. - }
  118. -
  119. - /*
  120. - * The result is used as the new evaluation set.
  121. - */
  122. - xmlXPathFreeObject(obj);
  123. - ctxt->context->node = NULL;
  124. - ctxt->context->contextSize = -1;
  125. - ctxt->context->proximityPosition = -1;
  126. - valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
  127. +xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt,
  128. + int nargs ATTRIBUTE_UNUSED) {
  129. + XP_ERROR(XPATH_EXPR_ERROR);
  130. }
  131. /**