-
-
Save anonymous/e10c9fb9e148c17cef44 to your computer and use it in GitHub Desktop.
Patch for 71587
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit b1bd4119bcafab6f9a8f84d92cd65eec3afeface | |
Author: Stanislav Malyshev <stas@php.net> | |
Date: Sun Feb 14 22:34:39 2016 -0800 | |
Fixed bug #71587 - Use-After-Free / Double-Free in WDDX Deserialize | |
diff --git a/ext/wddx/tests/bug71587.phpt b/ext/wddx/tests/bug71587.phpt | |
new file mode 100644 | |
index 0000000..3fdfc35 | |
--- /dev/null | |
+++ b/ext/wddx/tests/bug71587.phpt | |
@@ -0,0 +1,43 @@ | |
+--TEST-- | |
+Bug #71587 (Use-After-Free / Double-Free in WDDX Deserialize) | |
+--SKIPIF-- | |
+<?php | |
+if (!extension_loaded("wddx")) print "skip"; | |
+?> | |
+--FILE-- | |
+<?php | |
+ | |
+$xml = <<<EOF | |
+<?xml version='1.0' ?> | |
+<!DOCTYPE wddxPacket SYSTEM 'wddx_0100.dtd'> | |
+<wddxPacket version='1.0'> | |
+ <array> | |
+ <var name='ML'></var> | |
+ <string>manhluat</string> | |
+ <var name='ML2'></var> | |
+ <boolean value='a'/> | |
+ <boolean value='true'/> | |
+ </array> | |
+</wddxPacket> | |
+EOF; | |
+ | |
+$wddx = wddx_deserialize($xml); | |
+var_dump($wddx); | |
+// Print mem leak | |
+foreach($wddx as $k=>$v) | |
+ printf("Key: %s\nValue: %s\n",bin2hex($k),bin2hex($v)); | |
+ | |
+?> | |
+DONE | |
+--EXPECTF-- | |
+array(2) { | |
+ [0]=> | |
+ string(8) "manhluat" | |
+ [1]=> | |
+ bool(true) | |
+} | |
+Key: 30 | |
+Value: 6d616e686c756174 | |
+Key: 31 | |
+Value: 31 | |
+DONE | |
diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c | |
index 7267ee1..da34246 100644 | |
--- a/ext/wddx/wddx.c | |
+++ b/ext/wddx/wddx.c | |
@@ -936,6 +936,16 @@ static void php_wddx_pop_element(void *user_data, const XML_Char *name) | |
!strcmp(name, EL_DATETIME)) { | |
wddx_stack_top(stack, (void**)&ent1); | |
+ if (!ent1->data) { | |
+ if (stack->top > 1) { | |
+ stack->top--; | |
+ } else { | |
+ stack->done = 1; | |
+ } | |
+ efree(ent1); | |
+ return; | |
+ } | |
+ | |
if (!strcmp(name, EL_BINARY)) { | |
int new_len=0; | |
unsigned char *new_str; | |
@@ -1032,6 +1042,7 @@ static void php_wddx_pop_element(void *user_data, const XML_Char *name) | |
} | |
} else if (!strcmp(name, EL_VAR) && stack->varname) { | |
efree(stack->varname); | |
+ stack->varname = NULL; | |
} else if (!strcmp(name, EL_FIELD)) { | |
st_entry *ent; | |
wddx_stack_top(stack, (void **)&ent); | |
@@ -1051,7 +1062,7 @@ static void php_wddx_process_data(void *user_data, const XML_Char *s, int len) | |
if (!wddx_stack_is_empty(stack) && !stack->done) { | |
wddx_stack_top(stack, (void**)&ent); | |
- switch (Z_TYPE_P(ent)) { | |
+ switch (ent->type) { | |
case ST_STRING: | |
if (Z_STRLEN_P(ent->data) == 0) { | |
STR_FREE(Z_STRVAL_P(ent->data)); | |
@@ -1090,11 +1101,11 @@ static void php_wddx_process_data(void *user_data, const XML_Char *s, int len) | |
} else if (!strcmp(s, "false")) { | |
Z_LVAL_P(ent->data) = 0; | |
} else { | |
- stack->top--; | |
zval_ptr_dtor(&ent->data); | |
- if (ent->varname) | |
+ if (ent->varname) { | |
efree(ent->varname); | |
- efree(ent); | |
+ } | |
+ ent->data = NULL; | |
} | |
break; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment