summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnatol Belski <ab@php.net>2016-11-08 11:13:29 +0100
committerAnatol Belski <ab@php.net>2016-11-08 11:13:29 +0100
commit2b30b542750a917932fed29cafac83d40a045ffe (patch)
tree93730bf6b1787772a50d3ac9d2ff96674e697a24
parent5faaf76bd51818fb5954a12643a2de8f76120fcd (diff)
parentde643586dee986ff16c0a6be44813687786aa781 (diff)
downloadphp-git-2b30b542750a917932fed29cafac83d40a045ffe.tar.gz
Merge remote-tracking branch 'phpsec/PHP-7.0.13' into PHP-7.0
* phpsec/PHP-7.0.13: Fixed bug #73418 Integer Overflow in "_php_imap_mail" leads to crash Fix #72696: imagefilltoborder stackoverflow on truecolor images Fix #72482: Ilegal write/read access caused by gdImageAALine overflow Fix bug #73144 and bug #73341 - remove extra dtor remove unreferenced var came in with merge Fix bug #73331 - do not try to serialize/unserialize objects wddx can not handle fix version set versions
-rw-r--r--ext/gd/libgd/gd.c53
-rw-r--r--ext/gd/tests/bug72482.phpt19
-rw-r--r--ext/gd/tests/bug72482_2.phpt21
-rw-r--r--ext/gd/tests/bug72482_2.pngbin0 -> 118 bytes
-rw-r--r--ext/gd/tests/bug72696.phpt14
-rw-r--r--ext/imap/php_imap.c2
-rw-r--r--ext/pdo/pdo_stmt.c1
-rw-r--r--ext/standard/tests/serialize/bug73341.phpt24
-rw-r--r--ext/wddx/tests/bug45901.phpt4
-rw-r--r--ext/wddx/tests/bug72790.phpt2
-rw-r--r--ext/wddx/tests/bug73331.phpt15
-rw-r--r--ext/wddx/wddx.c51
12 files changed, 133 insertions, 73 deletions
diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c
index 99cbdde776..8d1e48dce5 100644
--- a/ext/gd/libgd/gd.c
+++ b/ext/gd/libgd/gd.c
@@ -1115,7 +1115,7 @@ void gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
}
/* 2.0.10: Nick Atty: clip to edges of drawing rectangle, return if no points need to be drawn */
- if (!clip_1d(&x1,&y1,&x2,&y2,gdImageSX(im)) || !clip_1d(&y1,&x1,&y2,&x2,gdImageSY(im))) {
+ if (!clip_1d(&x1,&y1,&x2,&y2,gdImageSX(im)-1) || !clip_1d(&y1,&x1,&y2,&x2,gdImageSY(im)-1)) {
return;
}
@@ -1299,55 +1299,10 @@ void gdImageAALine (gdImagePtr im, int x1, int y1, int x2, int y2, int col)
long x, y, inc, frac;
long dx, dy,tmp;
- if (y1 < 0 && y2 < 0) {
- return;
- }
- if (y1 < 0) {
- x1 += (y1 * (x1 - x2)) / (y2 - y1);
- y1 = 0;
- }
- if (y2 < 0) {
- x2 += (y2 * (x1 - x2)) / (y2 - y1);
- y2 = 0;
- }
-
- /* bottom edge */
- if (y1 >= im->sy && y2 >= im->sy) {
- return;
- }
- if (y1 >= im->sy) {
- x1 -= ((im->sy - y1) * (x1 - x2)) / (y2 - y1);
- y1 = im->sy - 1;
- }
- if (y2 >= im->sy) {
- x2 -= ((im->sy - y2) * (x1 - x2)) / (y2 - y1);
- y2 = im->sy - 1;
- }
-
- /* left edge */
- if (x1 < 0 && x2 < 0) {
- return;
- }
- if (x1 < 0) {
- y1 += (x1 * (y1 - y2)) / (x2 - x1);
- x1 = 0;
- }
- if (x2 < 0) {
- y2 += (x2 * (y1 - y2)) / (x2 - x1);
- x2 = 0;
- }
- /* right edge */
- if (x1 >= im->sx && x2 >= im->sx) {
+ /* 2.0.10: Nick Atty: clip to edges of drawing rectangle, return if no points need to be drawn */
+ if (!clip_1d(&x1,&y1,&x2,&y2,gdImageSX(im)-1) || !clip_1d(&y1,&x1,&y2,&x2,gdImageSY(im)-1)) {
return;
}
- if (x1 >= im->sx) {
- y1 -= ((im->sx - x1) * (y1 - y2)) / (x2 - x1);
- x1 = im->sx - 1;
- }
- if (x2 >= im->sx) {
- y2 -= ((im->sx - x2) * (y1 - y2)) / (x2 - x1);
- x2 = im->sx - 1;
- }
dx = x2 - x1;
dy = y2 - y1;
@@ -1790,7 +1745,7 @@ void gdImageFillToBorder (gdImagePtr im, int x, int y, int border, int color)
int leftLimit = -1, rightLimit;
int i, restoreAlphaBlending = 0;
- if (border < 0) {
+ if (border < 0 || color < 0) {
/* Refuse to fill to a non-solid border */
return;
}
diff --git a/ext/gd/tests/bug72482.phpt b/ext/gd/tests/bug72482.phpt
new file mode 100644
index 0000000000..548921d559
--- /dev/null
+++ b/ext/gd/tests/bug72482.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Bug #72482 (Ilegal write/read access caused by gdImageAALine overflow)
+--SKIPIF--
+<?php
+if (!extension_loaded('gd')) die('skip gd extension not available');
+?>
+--FILE--
+<?php
+$img = imagecreatetruecolor(13, 1007);
+imageantialias($img, true);
+imageline($img, 0, 0, 1073745919, 1073745919, 4096);
+
+$img = imagecreatetruecolor(100, 100);
+imageantialias($img, true);
+imageline($img, 1094795585, 0, 2147483647, 255, 0xff);
+?>
+===DONE===
+--EXPECT--
+===DONE===
diff --git a/ext/gd/tests/bug72482_2.phpt b/ext/gd/tests/bug72482_2.phpt
new file mode 100644
index 0000000000..a8a08faa53
--- /dev/null
+++ b/ext/gd/tests/bug72482_2.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Bug 72482 (Ilegal write/read access caused by gdImageAALine overflow)
+--SKIPIF--
+<?php
+if (!extension_loaded('gd')) die('skip gd extension not available');
+?>
+--FILE--
+<?php
+require_once __DIR__ . DIRECTORY_SEPARATOR . 'func.inc';
+
+$im = imagecreatetruecolor(10, 10);
+imagefilledrectangle($im, 0, 0, 9, 9, imagecolorallocate($im, 255, 255, 255));
+imageantialias($im, true);
+imageline($im, 0, 0, 10, 10, imagecolorallocate($im, 0, 0, 0));
+
+test_image_equals_file(__DIR__ . DIRECTORY_SEPARATOR . 'bug72482_2.png', $im);
+?>
+===DONE===
+--EXPECT--
+The images are equal.
+===DONE===
diff --git a/ext/gd/tests/bug72482_2.png b/ext/gd/tests/bug72482_2.png
new file mode 100644
index 0000000000..da90b2a267
--- /dev/null
+++ b/ext/gd/tests/bug72482_2.png
Binary files differ
diff --git a/ext/gd/tests/bug72696.phpt b/ext/gd/tests/bug72696.phpt
new file mode 100644
index 0000000000..4f0d9e7f1d
--- /dev/null
+++ b/ext/gd/tests/bug72696.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Bug #72696 (imagefilltoborder stackoverflow on truecolor images)
+--SKIPIF--
+<?php
+if (!extension_loaded('gd')) die('skip gd extension not available');
+?>
+--FILE--
+<?php
+$im = imagecreatetruecolor(10, 10);
+imagefilltoborder($im, 0, 0, 1, -2);
+?>
+===DONE===
+--EXPECT--
+===DONE===
diff --git a/ext/imap/php_imap.c b/ext/imap/php_imap.c
index a8eae27b0e..8ac5ed4150 100644
--- a/ext/imap/php_imap.c
+++ b/ext/imap/php_imap.c
@@ -3934,7 +3934,7 @@ int _php_imap_mail(char *to, char *subject, char *message, char *headers, char *
char *tsm_errmsg = NULL;
ADDRESS *addr;
char *bufferTo = NULL, *bufferCc = NULL, *bufferBcc = NULL, *bufferHeader = NULL;
- int offset, bufferLen = 0;
+ size_t offset, bufferLen = 0;
size_t bt_len;
if (headers) {
diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c
index d135467192..0ff8a04000 100644
--- a/ext/pdo/pdo_stmt.c
+++ b/ext/pdo/pdo_stmt.c
@@ -2299,6 +2299,7 @@ void pdo_stmt_init(void)
pdo_row_ce->ce_flags |= ZEND_ACC_FINAL; /* when removing this a lot of handlers need to be redone */
pdo_row_ce->create_object = pdo_row_new;
pdo_row_ce->serialize = pdo_row_serialize;
+ pdo_row_ce->unserialize = zend_class_unserialize_deny;
}
PDO_API void php_pdo_free_statement(pdo_stmt_t *stmt)
diff --git a/ext/standard/tests/serialize/bug73341.phpt b/ext/standard/tests/serialize/bug73341.phpt
new file mode 100644
index 0000000000..55423217c3
--- /dev/null
+++ b/ext/standard/tests/serialize/bug73341.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Bug #73144 (Use-afte-free in ArrayObject Deserialization)
+--FILE--
+<?php
+try {
+$token = 'a:2:{i:0;O:1:"0":2:0s:1:"0";i:0;s:1:"0";a:1:{i:0;C:11:"ArrayObject":7:0x:i:0;r0';
+$obj = unserialize($token);
+} catch(Exception $e) {
+ echo $e->getMessage()."\n";
+}
+
+try {
+$inner = 'x:i:1;O:8:"stdClass":1:{};m:a:0:{}';
+$exploit = 'C:11:"ArrayObject":'.strlen($inner).':{'.$inner.'}';
+unserialize($exploit);
+} catch(Exception $e) {
+ echo $e->getMessage()."\n";
+}
+?>
+--EXPECTF--
+Error at offset 6 of 7 bytes
+
+Notice: ArrayObject::unserialize(): Unexpected end of serialized data in %sbug73341.php on line %d
+Error at offset 24 of 34 bytes \ No newline at end of file
diff --git a/ext/wddx/tests/bug45901.phpt b/ext/wddx/tests/bug45901.phpt
index 4084ccbf20..e76e47eab7 100644
--- a/ext/wddx/tests/bug45901.phpt
+++ b/ext/wddx/tests/bug45901.phpt
@@ -14,5 +14,7 @@ echo wddx_serialize_value($xml, 'Variables') . "\n";
echo "DONE";
?>
--EXPECTF--
-<wddxPacket version='1.0'><header><comment>Variables</comment></header><data><struct><var name='php_class_name'><string>SimpleXMLElement</string></var><var name='test'><struct><var name='php_class_name'><string>SimpleXMLElement</string></var></struct></var></struct></data></wddxPacket>
+
+Warning: wddx_serialize_value(): Class SimpleXMLElement can not be serialized in %sbug45901.php on line %d
+<wddxPacket version='1.0'><header><comment>Variables</comment></header><data></data></wddxPacket>
DONE \ No newline at end of file
diff --git a/ext/wddx/tests/bug72790.phpt b/ext/wddx/tests/bug72790.phpt
index a60524bdaf..3b08e58cc6 100644
--- a/ext/wddx/tests/bug72790.phpt
+++ b/ext/wddx/tests/bug72790.phpt
@@ -1,5 +1,5 @@
--TEST--
-Bug 72790: wddx_deserialize null dereference with invalid xml
+Bug #72790: wddx_deserialize null dereference with invalid xml
--SKIPIF--
<?php
if (!extension_loaded('wddx')) {
diff --git a/ext/wddx/tests/bug73331.phpt b/ext/wddx/tests/bug73331.phpt
new file mode 100644
index 0000000000..7e4cda1ea1
--- /dev/null
+++ b/ext/wddx/tests/bug73331.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Bug #73331 (NULL Pointer Dereference in WDDX Packet Deserialization with PDORow)
+--SKIPIF--
+<?php if (!extension_loaded("wddx") || !extension_loaded("pdo")) print "skip"; ?>
+--FILE--
+<?php
+
+$wddx = "<wddxPacket version='1.0'><header/><data><struct><var name='php_class_name'><string>PDORow</string></var></struct></data></wddxPacket>";
+var_dump(wddx_deserialize($wddx));
+?>
+--EXPECTF--
+
+Warning: wddx_deserialize(): Class pdorow can not be unserialized in %s73331.php on line %d
+NULL
+
diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c
index 7d805e484f..e21d178edf 100644
--- a/ext/wddx/wddx.c
+++ b/ext/wddx/wddx.c
@@ -453,6 +453,16 @@ static void php_wddx_serialize_object(wddx_packet *packet, zval *obj)
zend_ulong idx;
char tmp_buf[WDDX_BUF_LEN];
HashTable *objhash, *sleephash;
+ zend_class_entry *ce;
+ PHP_CLASS_ATTRIBUTES;
+
+ PHP_SET_CLASS_ATTRIBUTES(obj);
+ ce = Z_OBJCE_P(obj);
+ if (!ce || ce->serialize || ce->unserialize) {
+ php_error_docref(NULL, E_WARNING, "Class %s can not be serialized", ZSTR_VAL(class_name));
+ PHP_CLEANUP_CLASS_ATTRIBUTES();
+ return;
+ }
ZVAL_STRING(&fname, "__sleep");
/*
@@ -473,8 +483,6 @@ static void php_wddx_serialize_object(wddx_packet *packet, zval *obj)
php_wddx_add_chunk_static(packet, WDDX_STRING_E);
php_wddx_add_chunk_static(packet, WDDX_VAR_E);
- PHP_CLEANUP_CLASS_ATTRIBUTES();
-
objhash = Z_OBJPROP_P(obj);
ZEND_HASH_FOREACH_VAL(sleephash, varname) {
@@ -491,10 +499,6 @@ static void php_wddx_serialize_object(wddx_packet *packet, zval *obj)
php_wddx_add_chunk_static(packet, WDDX_STRUCT_E);
}
} else {
- PHP_CLASS_ATTRIBUTES;
-
- PHP_SET_CLASS_ATTRIBUTES(obj);
-
php_wddx_add_chunk_static(packet, WDDX_STRUCT_S);
snprintf(tmp_buf, WDDX_BUF_LEN, WDDX_VAR_S, PHP_CLASS_NAME_VAR);
php_wddx_add_chunk(packet, tmp_buf);
@@ -503,8 +507,6 @@ static void php_wddx_serialize_object(wddx_packet *packet, zval *obj)
php_wddx_add_chunk_static(packet, WDDX_STRING_E);
php_wddx_add_chunk_static(packet, WDDX_VAR_E);
- PHP_CLEANUP_CLASS_ATTRIBUTES();
-
objhash = Z_OBJPROP_P(obj);
ZEND_HASH_FOREACH_KEY_VAL(objhash, idx, key, ent) {
if (ent == obj) {
@@ -528,6 +530,8 @@ static void php_wddx_serialize_object(wddx_packet *packet, zval *obj)
php_wddx_add_chunk_static(packet, WDDX_STRUCT_E);
}
+ PHP_CLEANUP_CLASS_ATTRIBUTES();
+
zval_ptr_dtor(&fname);
zval_ptr_dtor(&retval);
}
@@ -947,23 +951,28 @@ static void php_wddx_pop_element(void *user_data, const XML_Char *name)
pce = PHP_IC_ENTRY;
}
- /* Initialize target object */
- object_init_ex(&obj, pce);
+ if (pce != PHP_IC_ENTRY && (pce->serialize || pce->unserialize)) {
+ ZVAL_UNDEF(&ent2->data);
+ php_error_docref(NULL, E_WARNING, "Class %s can not be unserialized", Z_STRVAL(ent1->data));
+ } else {
+ /* Initialize target object */
+ object_init_ex(&obj, pce);
- /* Merge current hashtable with object's default properties */
- zend_hash_merge(Z_OBJPROP(obj),
- Z_ARRVAL(ent2->data),
- zval_add_ref, 0);
+ /* Merge current hashtable with object's default properties */
+ zend_hash_merge(Z_OBJPROP(obj),
+ Z_ARRVAL(ent2->data),
+ zval_add_ref, 0);
- if (incomplete_class) {
- php_store_class_name(&obj, Z_STRVAL(ent1->data), Z_STRLEN(ent1->data));
- }
+ if (incomplete_class) {
+ php_store_class_name(&obj, Z_STRVAL(ent1->data), Z_STRLEN(ent1->data));
+ }
- /* Clean up old array entry */
- zval_ptr_dtor(&ent2->data);
+ /* Clean up old array entry */
+ zval_ptr_dtor(&ent2->data);
- /* Set stack entry to point to the newly created object */
- ZVAL_COPY_VALUE(&ent2->data, &obj);
+ /* Set stack entry to point to the newly created object */
+ ZVAL_COPY_VALUE(&ent2->data, &obj);
+ }
/* Clean up class name var entry */
zval_ptr_dtor(&ent1->data);