You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

128 lines
3.6 KiB

From: =?utf-8?q?Ond=C5=99ej_Sur=C3=BD?= <ondrej@sury.org>
Date: Sat, 8 Apr 2017 10:40:20 +0200
Subject: Fix PHP bug #64827: Segfault in zval_mark_grey (zend_gc.c)
---
Zend/zend_gc.c | 84 +++++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 59 insertions(+), 25 deletions(-)
diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c
index e72655c..e7c5098 100644
--- a/Zend/zend_gc.c
+++ b/Zend/zend_gc.c
@@ -310,16 +310,25 @@ tail_call:
}
}
while (p != NULL) {
- pz = *(zval**)p->pData;
- if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
- pz->refcount__gc++;
- }
- if (GC_ZVAL_GET_COLOR(pz) != GC_BLACK) {
- if (p->pListNext == NULL) {
- goto tail_call;
+ if (p->pData != NULL) {
+ pz = *(zval**)p->pData;
+ if (pz != NULL) {
+ if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
+ pz->refcount__gc++;
+ }
+ if (GC_ZVAL_GET_COLOR(pz) != GC_BLACK) {
+ if (p->pListNext == NULL) {
+ goto tail_call;
+ } else {
+ zval_scan_black(pz TSRMLS_CC);
+ }
+ }
} else {
- zval_scan_black(pz TSRMLS_CC);
+ /* Now this is really odd ... we've got a p->pData which references a NULL pointer */
}
+ } else {
+ /* shall we log something when encountering a p->pData == NULL */
+
}
p = p->pListNext;
}
@@ -353,12 +362,20 @@ static void zobj_scan_black(struct _store_object *obj, zval *pz TSRMLS_DC)
}
p = props->pListHead;
while (p != NULL) {
- pz = *(zval**)p->pData;
- if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
- pz->refcount__gc++;
- }
- if (GC_ZVAL_GET_COLOR(pz) != GC_BLACK) {
- zval_scan_black(pz TSRMLS_CC);
+ if (p->pData != NULL) {
+ pz = *(zval**)p->pData;
+ if (pz != NULL) {
+ if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
+ pz->refcount__gc++;
+ }
+ if (GC_ZVAL_GET_COLOR(pz) != GC_BLACK) {
+ zval_scan_black(pz TSRMLS_CC);
+ }
+ } else {
+ /* pz is NULL - maybe there should be some logging? */
+ }
+ } else {
+ /* p->pData is NULL - maybe there should be some logging? */
}
p = p->pListNext;
}
@@ -417,14 +434,23 @@ tail_call:
}
}
while (p != NULL) {
- pz = *(zval**)p->pData;
- if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
- pz->refcount__gc--;
- }
- if (p->pListNext == NULL) {
- goto tail_call;
+ if (p->pData != NULL) {
+ pz = *(zval**)p->pData;
+ if (pz != NULL) {
+ if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
+ pz->refcount__gc--;
+ }
+ if (p->pListNext == NULL) {
+ goto tail_call;
+ } else {
+ zval_mark_grey(pz TSRMLS_CC);
+ }
+ } else {
+ /* Now this is odd - we have a valid pz and a pData which is NULL */
+
+ }
} else {
- zval_mark_grey(pz TSRMLS_CC);
+ /* Some logging maybe? p->pData is NULL */
}
p = p->pListNext;
}
@@ -459,11 +485,19 @@ static void zobj_mark_grey(struct _store_object *obj, zval *pz TSRMLS_DC)
}
p = props->pListHead;
while (p != NULL) {
- pz = *(zval**)p->pData;
- if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
- pz->refcount__gc--;
+ if (p->pData != NULL) {
+ pz = *(zval**)p->pData;
+ if (pz != NULL) {
+ if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
+ pz->refcount__gc--;
+ }
+ zval_mark_grey(pz TSRMLS_CC);
+ } else {
+ /* TODO: Some logging maybe? */
+ }
+ } else {
+ /* TODO: Some logging maybe? */
}
- zval_mark_grey(pz TSRMLS_CC);
p = p->pListNext;
}
}