0001-Fix-XPointer-paths-beginning-with-range-to.patch 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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. Signed-off-by: Baruch Siach <baruch@tkos.co.il>
  13. ---
  14. Patch status: upstream commit 9ab01a277d7
  15. result/XPath/xptr/vidbase | 13 ++++++++
  16. test/XPath/xptr/vidbase | 1 +
  17. xpath.c | 7 ++++-
  18. xpointer.c | 76 ++++-------------------------------------------
  19. 4 files changed, 26 insertions(+), 71 deletions(-)
  20. diff --git a/result/XPath/xptr/vidbase b/result/XPath/xptr/vidbase
  21. index 8b9e92d66d97..f19193e70edb 100644
  22. --- a/result/XPath/xptr/vidbase
  23. +++ b/result/XPath/xptr/vidbase
  24. @@ -17,3 +17,16 @@ Object is a Location Set:
  25. To node
  26. ELEMENT p
  27. +
  28. +========================
  29. +Expression: xpointer(range-to(id('chapter2')))
  30. +Object is a Location Set:
  31. +1 : Object is a range :
  32. + From node
  33. + /
  34. + To node
  35. + ELEMENT chapter
  36. + ATTRIBUTE id
  37. + TEXT
  38. + content=chapter2
  39. +
  40. diff --git a/test/XPath/xptr/vidbase b/test/XPath/xptr/vidbase
  41. index b1463830570a..884b1065d7fd 100644
  42. --- a/test/XPath/xptr/vidbase
  43. +++ b/test/XPath/xptr/vidbase
  44. @@ -1,2 +1,3 @@
  45. xpointer(id('chapter1')/p)
  46. xpointer(id('chapter1')/p[1]/range-to(following-sibling::p[2]))
  47. +xpointer(range-to(id('chapter2')))
  48. diff --git a/xpath.c b/xpath.c
  49. index d992841ef0c2..5a01b1b399a2 100644
  50. --- a/xpath.c
  51. +++ b/xpath.c
  52. @@ -10691,13 +10691,18 @@ xmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) {
  53. lc = 1;
  54. break;
  55. } else if ((NXT(len) == '(')) {
  56. - /* Note Type or Function */
  57. + /* Node Type or Function */
  58. if (xmlXPathIsNodeType(name)) {
  59. #ifdef DEBUG_STEP
  60. xmlGenericError(xmlGenericErrorContext,
  61. "PathExpr: Type search\n");
  62. #endif
  63. lc = 1;
  64. +#ifdef LIBXML_XPTR_ENABLED
  65. + } else if (ctxt->xptr &&
  66. + xmlStrEqual(name, BAD_CAST "range-to")) {
  67. + lc = 1;
  68. +#endif
  69. } else {
  70. #ifdef DEBUG_STEP
  71. xmlGenericError(xmlGenericErrorContext,
  72. diff --git a/xpointer.c b/xpointer.c
  73. index 676c5105837a..d74174a318f1 100644
  74. --- a/xpointer.c
  75. +++ b/xpointer.c
  76. @@ -1332,8 +1332,6 @@ xmlXPtrNewContext(xmlDocPtr doc, xmlNodePtr here, xmlNodePtr origin) {
  77. ret->here = here;
  78. ret->origin = origin;
  79. - xmlXPathRegisterFunc(ret, (xmlChar *)"range-to",
  80. - xmlXPtrRangeToFunction);
  81. xmlXPathRegisterFunc(ret, (xmlChar *)"range",
  82. xmlXPtrRangeFunction);
  83. xmlXPathRegisterFunc(ret, (xmlChar *)"range-inside",
  84. @@ -2243,76 +2241,14 @@ xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs) {
  85. * @nargs: the number of args
  86. *
  87. * Implement the range-to() XPointer function
  88. + *
  89. + * Obsolete. range-to is not a real function but a special type of location
  90. + * step which is handled in xpath.c.
  91. */
  92. void
  93. -xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt, int nargs) {
  94. - xmlXPathObjectPtr range;
  95. - const xmlChar *cur;
  96. - xmlXPathObjectPtr res, obj;
  97. - xmlXPathObjectPtr tmp;
  98. - xmlLocationSetPtr newset = NULL;
  99. - xmlNodeSetPtr oldset;
  100. - int i;
  101. -
  102. - if (ctxt == NULL) return;
  103. - CHECK_ARITY(1);
  104. - /*
  105. - * Save the expression pointer since we will have to evaluate
  106. - * it multiple times. Initialize the new set.
  107. - */
  108. - CHECK_TYPE(XPATH_NODESET);
  109. - obj = valuePop(ctxt);
  110. - oldset = obj->nodesetval;
  111. - ctxt->context->node = NULL;
  112. -
  113. - cur = ctxt->cur;
  114. - newset = xmlXPtrLocationSetCreate(NULL);
  115. -
  116. - for (i = 0; i < oldset->nodeNr; i++) {
  117. - ctxt->cur = cur;
  118. -
  119. - /*
  120. - * Run the evaluation with a node list made of a single item
  121. - * in the nodeset.
  122. - */
  123. - ctxt->context->node = oldset->nodeTab[i];
  124. - tmp = xmlXPathNewNodeSet(ctxt->context->node);
  125. - valuePush(ctxt, tmp);
  126. -
  127. - xmlXPathEvalExpr(ctxt);
  128. - CHECK_ERROR;
  129. -
  130. - /*
  131. - * The result of the evaluation need to be tested to
  132. - * decided whether the filter succeeded or not
  133. - */
  134. - res = valuePop(ctxt);
  135. - range = xmlXPtrNewRangeNodeObject(oldset->nodeTab[i], res);
  136. - if (range != NULL) {
  137. - xmlXPtrLocationSetAdd(newset, range);
  138. - }
  139. -
  140. - /*
  141. - * Cleanup
  142. - */
  143. - if (res != NULL)
  144. - xmlXPathFreeObject(res);
  145. - if (ctxt->value == tmp) {
  146. - res = valuePop(ctxt);
  147. - xmlXPathFreeObject(res);
  148. - }
  149. -
  150. - ctxt->context->node = NULL;
  151. - }
  152. -
  153. - /*
  154. - * The result is used as the new evaluation set.
  155. - */
  156. - xmlXPathFreeObject(obj);
  157. - ctxt->context->node = NULL;
  158. - ctxt->context->contextSize = -1;
  159. - ctxt->context->proximityPosition = -1;
  160. - valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
  161. +xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt,
  162. + int nargs ATTRIBUTE_UNUSED) {
  163. + XP_ERROR(XPATH_EXPR_ERROR);
  164. }
  165. /**
  166. --
  167. 2.10.2