diff options
-rw-r--r-- | ext/phar/tests/bug71488.phpt | 1 | ||||
-rw-r--r-- | ext/phar/tests/bug71498.phpt | 17 | ||||
-rw-r--r-- | ext/phar/tests/bug71498.zip | bin | 0 -> 65677 bytes | |||
-rw-r--r-- | ext/phar/zip.c | 6 | ||||
-rw-r--r-- | ext/wddx/tests/bug71587.phpt | 43 | ||||
-rw-r--r-- | ext/wddx/wddx.c | 19 |
6 files changed, 79 insertions, 7 deletions
diff --git a/ext/phar/tests/bug71488.phpt b/ext/phar/tests/bug71488.phpt index 05fdd8f481..22d2bf098f 100644 --- a/ext/phar/tests/bug71488.phpt +++ b/ext/phar/tests/bug71488.phpt @@ -7,6 +7,7 @@ Phar: bug #71488: Stack overflow when decompressing tar archives $p = new PharData(__DIR__."/bug71488.tar"); $newp = $p->decompress("test"); ?> + DONE --CLEAN-- <?php diff --git a/ext/phar/tests/bug71498.phpt b/ext/phar/tests/bug71498.phpt new file mode 100644 index 0000000000..de6283c8dc --- /dev/null +++ b/ext/phar/tests/bug71498.phpt @@ -0,0 +1,17 @@ +--TEST-- +Phar: bug #71498: Out-of-Bound Read in phar_parse_zipfile() +--SKIPIF-- +<?php if (!extension_loaded("phar")) die("skip"); ?> +--FILE-- +<?php +try { +$p = new PharData(__DIR__."/bug71498.zip"); +} catch(UnexpectedValueException $e) { + echo $e->getMessage(); +} +?> + +DONE +--EXPECTF-- +phar error: end of central directory not found in zip-based phar "%s/bug71498.zip" +DONE
\ No newline at end of file diff --git a/ext/phar/tests/bug71498.zip b/ext/phar/tests/bug71498.zip Binary files differnew file mode 100644 index 0000000000..ae78dd871e --- /dev/null +++ b/ext/phar/tests/bug71498.zip diff --git a/ext/phar/zip.c b/ext/phar/zip.c index 3d6880f751..2f1d915146 100644 --- a/ext/phar/zip.c +++ b/ext/phar/zip.c @@ -159,7 +159,7 @@ static void phar_zip_u2d_time(time_t time, char *dtime, char *ddate) /* {{{ */ * * Parse a new one and add it to the cache, returning either SUCCESS or * FAILURE, and setting pphar to the pointer to the manifest entry - * + * * This is used by phar_open_from_fp to process a zip-based phar, but can be called * directly. */ @@ -199,7 +199,7 @@ int phar_parse_zipfile(php_stream *fp, char *fname, int fname_len, char *alias, } while ((p=(char *) memchr(p + 1, 'P', (size_t) (size - (p + 1 - buf)))) != NULL) { - if (!memcmp(p + 1, "K\5\6", 3)) { + if ((p - buf) + sizeof(locator) <= size && !memcmp(p + 1, "K\5\6", 3)) { memcpy((void *)&locator, (void *) p, sizeof(locator)); if (PHAR_GET_16(locator.centraldisk) != 0 || PHAR_GET_16(locator.disknumber) != 0) { /* split archives not handled */ @@ -1161,7 +1161,7 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau static const char newstub[] = "<?php // zip-based phar archive stub file\n__HALT_COMPILER();"; char halt_stub[] = "__HALT_COMPILER();"; char *tmp; - + php_stream *stubfile, *oldfile; php_serialize_data_t metadata_hash; int free_user_stub, closeoldfile = 0; diff --git a/ext/wddx/tests/bug71587.phpt b/ext/wddx/tests/bug71587.phpt new file mode 100644 index 0000000000..3fdfc35c16 --- /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 93526f56a1..22ff535c63 100644 --- a/ext/wddx/wddx.c +++ b/ext/wddx/wddx.c @@ -934,6 +934,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; @@ -1030,6 +1040,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); @@ -1049,7 +1060,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)); @@ -1088,11 +1099,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; |