1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
Author: Alastair McKinstry <mckinstry@debian.org>
Description: Fix for recursion errors:
CVE-2016-4570 Recursion using mxmlDelete at mxml-node.c:217 (stack-exhaustion-1.xml)
CVE-2016-4571 Recursion using mxml_write_node at mxml-file.c:2739 (stack-exhaustion-2.xml
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=825855
Last-Updated: 2016-06-10
Forwarded: yes
Index: mxml-2.9/mxml-node.c
===================================================================
--- mxml-2.9.orig/mxml-node.c
+++ mxml-2.9/mxml-node.c
@@ -21,7 +21,7 @@
#include "config.h"
#include "mxml.h"
-
+#include "mxml-private.h"
/*
* Local functions...
*/
@@ -174,12 +174,12 @@ mxmlAdd(mxml_node_t *parent, /* I - Par
* node from its parent using the mxmlRemove() function.
*/
-void
-mxmlDelete(mxml_node_t *node) /* I - Node to delete */
+
+static void
+mxmlDeleteLimited(mxml_node_t *node, int max_depth) /* I - Node to delete */
{
int i; /* Looping var */
-
-
+
#ifdef DEBUG
fprintf(stderr, "mxmlDelete(node=%p)\n", node);
#endif /* DEBUG */
@@ -201,9 +201,15 @@ mxmlDelete(mxml_node_t *node) /* I - No
* Delete children...
*/
- while (node->child)
- mxmlDelete(node->child);
-
+ while (node->child) {
+ if (max_depth <= 0) {
+ mxml_error("Maximum recursion depth reached");
+ return;
+ } else {
+ mxmlDeleteLimited(node->child, max_depth-1);
+ }
+ }
+
/*
* Now delete any node data...
*/
@@ -257,6 +263,11 @@ mxmlDelete(mxml_node_t *node) /* I - No
free(node);
}
+void
+mxmlDelete(mxml_node_t *node) /* I - Node to delete */
+{
+ mxmlDeleteLimited(node, MAX_DEPTH);
+}
/*
* 'mxmlGetRefCount()' - Get the current reference (use) count for a node.
Index: mxml-2.9/mxml-file.c
===================================================================
--- mxml-2.9.orig/mxml-file.c
+++ mxml-2.9/mxml-file.c
@@ -90,7 +90,8 @@ static int mxml_write_name(const char *
static int mxml_write_node(mxml_node_t *node, void *p,
mxml_save_cb_t cb, int col,
_mxml_putc_cb_t putc_cb,
- _mxml_global_t *global);
+ _mxml_global_t *global,
+ int max_depth);
static int mxml_write_string(const char *s, void *p,
_mxml_putc_cb_t putc_cb);
static int mxml_write_ws(mxml_node_t *node, void *p,
@@ -290,7 +291,7 @@ mxmlSaveFd(mxml_node_t *node, /* I -
* Write the node...
*/
- if ((col = mxml_write_node(node, &buf, cb, 0, mxml_fd_putc, global)) < 0)
+ if ((col = mxml_write_node(node, &buf, cb, 0, mxml_fd_putc, global,MAX_DEPTH)) < 0)
return (-1);
if (col > 0)
@@ -329,7 +330,7 @@ mxmlSaveFile(mxml_node_t *node, /* I
* Write the node...
*/
- if ((col = mxml_write_node(node, fp, cb, 0, mxml_file_putc, global)) < 0)
+ if ((col = mxml_write_node(node, fp, cb, 0, mxml_file_putc, global, MAX_DEPTH)) < 0)
return (-1);
if (col > 0)
@@ -377,7 +378,7 @@ mxmlSaveString(mxml_node_t *node, /*
ptr[0] = buffer;
ptr[1] = buffer + bufsize;
- if ((col = mxml_write_node(node, ptr, cb, 0, mxml_string_putc, global)) < 0)
+ if ((col = mxml_write_node(node, ptr, cb, 0, mxml_string_putc, global, MAX_DEPTH)) < 0)
return (-1);
if (col > 0)
@@ -2708,7 +2709,8 @@ mxml_write_node(mxml_node_t *node, /
mxml_save_cb_t cb, /* I - Whitespace callback */
int col, /* I - Current column */
_mxml_putc_cb_t putc_cb,/* I - Output callback */
- _mxml_global_t *global)/* I - Global data */
+ _mxml_global_t *global,/* I - Global data */
+ int max_depth)/*I - recursion limit */
{
int i, /* Looping var */
width; /* Width of attr + value */
@@ -2808,7 +2810,11 @@ mxml_write_node(mxml_node_t *node, /
for (child = node->child; child; child = child->next)
{
- if ((col = mxml_write_node(child, p, cb, col, putc_cb, global)) < 0)
+ if (max_depth <= 0) {
+ mxml_error("Recursion limit reached");
+ return (-1);
+ }
+ if ((col = mxml_write_node(child, p, cb, col, putc_cb, global, max_depth-1)) < 0)
return (-1);
}
Index: mxml-2.9/mxml-private.h
===================================================================
--- mxml-2.9.orig/mxml-private.h
+++ mxml-2.9/mxml-private.h
@@ -22,6 +22,8 @@
#include "mxml.h"
+#define MAX_DEPTH 1000 /* Max. recursion depth */
+
/*
* Global, per-thread data...
*/
|