0002-Disallow-namespace-nodes-in-XPointer-ranges.patch 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. From c1d1f7121194036608bf555f08d3062a36fd344b Mon Sep 17 00:00:00 2001
  2. From: Nick Wellnhofer <wellnhofer@aevum.de>
  3. Date: Tue, 28 Jun 2016 18:34:52 +0200
  4. Subject: [PATCH] Disallow namespace nodes in XPointer ranges
  5. Namespace nodes must be copied to avoid use-after-free errors.
  6. But they don't necessarily have a physical representation in a
  7. document, so simply disallow them in XPointer ranges.
  8. Found with afl-fuzz.
  9. Fixes CVE-2016-4658.
  10. Signed-off-by: Baruch Siach <baruch@tkos.co.il>
  11. ---
  12. Patch status: upstream commit c1d1f712119403
  13. xpointer.c | 149 +++++++++++++++++++++++--------------------------------------
  14. 1 file changed, 56 insertions(+), 93 deletions(-)
  15. diff --git a/xpointer.c b/xpointer.c
  16. index a7b03fbdae16..694d120e2e0b 100644
  17. --- a/xpointer.c
  18. +++ b/xpointer.c
  19. @@ -320,6 +320,45 @@ xmlXPtrRangesEqual(xmlXPathObjectPtr range1, xmlXPathObjectPtr range2) {
  20. }
  21. /**
  22. + * xmlXPtrNewRangeInternal:
  23. + * @start: the starting node
  24. + * @startindex: the start index
  25. + * @end: the ending point
  26. + * @endindex: the ending index
  27. + *
  28. + * Internal function to create a new xmlXPathObjectPtr of type range
  29. + *
  30. + * Returns the newly created object.
  31. + */
  32. +static xmlXPathObjectPtr
  33. +xmlXPtrNewRangeInternal(xmlNodePtr start, int startindex,
  34. + xmlNodePtr end, int endindex) {
  35. + xmlXPathObjectPtr ret;
  36. +
  37. + /*
  38. + * Namespace nodes must be copied (see xmlXPathNodeSetDupNs).
  39. + * Disallow them for now.
  40. + */
  41. + if ((start != NULL) && (start->type == XML_NAMESPACE_DECL))
  42. + return(NULL);
  43. + if ((end != NULL) && (end->type == XML_NAMESPACE_DECL))
  44. + return(NULL);
  45. +
  46. + ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
  47. + if (ret == NULL) {
  48. + xmlXPtrErrMemory("allocating range");
  49. + return(NULL);
  50. + }
  51. + memset(ret, 0, sizeof(xmlXPathObject));
  52. + ret->type = XPATH_RANGE;
  53. + ret->user = start;
  54. + ret->index = startindex;
  55. + ret->user2 = end;
  56. + ret->index2 = endindex;
  57. + return(ret);
  58. +}
  59. +
  60. +/**
  61. * xmlXPtrNewRange:
  62. * @start: the starting node
  63. * @startindex: the start index
  64. @@ -344,17 +383,7 @@ xmlXPtrNewRange(xmlNodePtr start, int startindex,
  65. if (endindex < 0)
  66. return(NULL);
  67. - ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
  68. - if (ret == NULL) {
  69. - xmlXPtrErrMemory("allocating range");
  70. - return(NULL);
  71. - }
  72. - memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
  73. - ret->type = XPATH_RANGE;
  74. - ret->user = start;
  75. - ret->index = startindex;
  76. - ret->user2 = end;
  77. - ret->index2 = endindex;
  78. + ret = xmlXPtrNewRangeInternal(start, startindex, end, endindex);
  79. xmlXPtrRangeCheckOrder(ret);
  80. return(ret);
  81. }
  82. @@ -381,17 +410,8 @@ xmlXPtrNewRangePoints(xmlXPathObjectPtr start, xmlXPathObjectPtr end) {
  83. if (end->type != XPATH_POINT)
  84. return(NULL);
  85. - ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
  86. - if (ret == NULL) {
  87. - xmlXPtrErrMemory("allocating range");
  88. - return(NULL);
  89. - }
  90. - memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
  91. - ret->type = XPATH_RANGE;
  92. - ret->user = start->user;
  93. - ret->index = start->index;
  94. - ret->user2 = end->user;
  95. - ret->index2 = end->index;
  96. + ret = xmlXPtrNewRangeInternal(start->user, start->index, end->user,
  97. + end->index);
  98. xmlXPtrRangeCheckOrder(ret);
  99. return(ret);
  100. }
  101. @@ -416,17 +436,7 @@ xmlXPtrNewRangePointNode(xmlXPathObjectPtr start, xmlNodePtr end) {
  102. if (start->type != XPATH_POINT)
  103. return(NULL);
  104. - ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
  105. - if (ret == NULL) {
  106. - xmlXPtrErrMemory("allocating range");
  107. - return(NULL);
  108. - }
  109. - memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
  110. - ret->type = XPATH_RANGE;
  111. - ret->user = start->user;
  112. - ret->index = start->index;
  113. - ret->user2 = end;
  114. - ret->index2 = -1;
  115. + ret = xmlXPtrNewRangeInternal(start->user, start->index, end, -1);
  116. xmlXPtrRangeCheckOrder(ret);
  117. return(ret);
  118. }
  119. @@ -453,17 +463,7 @@ xmlXPtrNewRangeNodePoint(xmlNodePtr start, xmlXPathObjectPtr end) {
  120. if (end->type != XPATH_POINT)
  121. return(NULL);
  122. - ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
  123. - if (ret == NULL) {
  124. - xmlXPtrErrMemory("allocating range");
  125. - return(NULL);
  126. - }
  127. - memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
  128. - ret->type = XPATH_RANGE;
  129. - ret->user = start;
  130. - ret->index = -1;
  131. - ret->user2 = end->user;
  132. - ret->index2 = end->index;
  133. + ret = xmlXPtrNewRangeInternal(start, -1, end->user, end->index);
  134. xmlXPtrRangeCheckOrder(ret);
  135. return(ret);
  136. }
  137. @@ -486,17 +486,7 @@ xmlXPtrNewRangeNodes(xmlNodePtr start, xmlNodePtr end) {
  138. if (end == NULL)
  139. return(NULL);
  140. - ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
  141. - if (ret == NULL) {
  142. - xmlXPtrErrMemory("allocating range");
  143. - return(NULL);
  144. - }
  145. - memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
  146. - ret->type = XPATH_RANGE;
  147. - ret->user = start;
  148. - ret->index = -1;
  149. - ret->user2 = end;
  150. - ret->index2 = -1;
  151. + ret = xmlXPtrNewRangeInternal(start, -1, end, -1);
  152. xmlXPtrRangeCheckOrder(ret);
  153. return(ret);
  154. }
  155. @@ -516,17 +506,7 @@ xmlXPtrNewCollapsedRange(xmlNodePtr start) {
  156. if (start == NULL)
  157. return(NULL);
  158. - ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
  159. - if (ret == NULL) {
  160. - xmlXPtrErrMemory("allocating range");
  161. - return(NULL);
  162. - }
  163. - memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
  164. - ret->type = XPATH_RANGE;
  165. - ret->user = start;
  166. - ret->index = -1;
  167. - ret->user2 = NULL;
  168. - ret->index2 = -1;
  169. + ret = xmlXPtrNewRangeInternal(start, -1, NULL, -1);
  170. return(ret);
  171. }
  172. @@ -541,6 +521,8 @@ xmlXPtrNewCollapsedRange(xmlNodePtr start) {
  173. */
  174. xmlXPathObjectPtr
  175. xmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) {
  176. + xmlNodePtr endNode;
  177. + int endIndex;
  178. xmlXPathObjectPtr ret;
  179. if (start == NULL)
  180. @@ -549,7 +531,12 @@ xmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) {
  181. return(NULL);
  182. switch (end->type) {
  183. case XPATH_POINT:
  184. + endNode = end->user;
  185. + endIndex = end->index;
  186. + break;
  187. case XPATH_RANGE:
  188. + endNode = end->user2;
  189. + endIndex = end->index2;
  190. break;
  191. case XPATH_NODESET:
  192. /*
  193. @@ -557,39 +544,15 @@ xmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) {
  194. */
  195. if (end->nodesetval->nodeNr <= 0)
  196. return(NULL);
  197. + endNode = end->nodesetval->nodeTab[end->nodesetval->nodeNr - 1];
  198. + endIndex = -1;
  199. break;
  200. default:
  201. /* TODO */
  202. return(NULL);
  203. }
  204. - ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
  205. - if (ret == NULL) {
  206. - xmlXPtrErrMemory("allocating range");
  207. - return(NULL);
  208. - }
  209. - memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
  210. - ret->type = XPATH_RANGE;
  211. - ret->user = start;
  212. - ret->index = -1;
  213. - switch (end->type) {
  214. - case XPATH_POINT:
  215. - ret->user2 = end->user;
  216. - ret->index2 = end->index;
  217. - break;
  218. - case XPATH_RANGE:
  219. - ret->user2 = end->user2;
  220. - ret->index2 = end->index2;
  221. - break;
  222. - case XPATH_NODESET: {
  223. - ret->user2 = end->nodesetval->nodeTab[end->nodesetval->nodeNr - 1];
  224. - ret->index2 = -1;
  225. - break;
  226. - }
  227. - default:
  228. - STRANGE
  229. - return(NULL);
  230. - }
  231. + ret = xmlXPtrNewRangeInternal(start, -1, endNode, endIndex);
  232. xmlXPtrRangeCheckOrder(ret);
  233. return(ret);
  234. }
  235. --
  236. 2.10.2