Skip to content

Commit

Permalink
Fix phpGH-17442: Engine UAF with reference assign and dtor
Browse files Browse the repository at this point in the history
  • Loading branch information
nielsdos committed Jan 11, 2025
1 parent a2a7287 commit 9ab9dc2
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 16 deletions.
22 changes: 22 additions & 0 deletions Zend/tests/weakrefs/gh17442.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
--TEST--
GH-17442 (Engine UAF with reference assign and dtor)
--CREDITS--
YuanchengJiang
--FILE--
<?php
$map = new WeakMap;
$obj = new stdClass;
$map[$obj] = new class {
function __destruct() {
throw new Exception("Test");
}
};
headers_sent($obj,$generator);
?>
--EXPECTF--
Fatal error: Uncaught Exception: Test in %s:%d
Stack trace:
#0 [internal function]: class@anonymous->__destruct()
#1 %s(%d): headers_sent('', 0)
#2 {main}
thrown in %s on line %d
64 changes: 48 additions & 16 deletions Zend/zend_API.h
Original file line number Diff line number Diff line change
Expand Up @@ -1100,8 +1100,10 @@ ZEND_API zend_result zend_try_assign_typed_ref_zval_ex(zend_reference *ref, zval
} \
_zv = &ref->val; \
} \
zval_ptr_dtor(_zv); \
zval garbage; \
ZVAL_COPY_VALUE(&garbage, _zv); \
ZVAL_NULL(_zv); \
zval_ptr_dtor(&garbage); \
} while (0)

#define ZEND_TRY_ASSIGN_NULL(zv) \
Expand All @@ -1122,8 +1124,10 @@ ZEND_API zend_result zend_try_assign_typed_ref_zval_ex(zend_reference *ref, zval
} \
_zv = &ref->val; \
} \
zval_ptr_dtor(_zv); \
zval garbage; \
ZVAL_COPY_VALUE(&garbage, _zv); \
ZVAL_FALSE(_zv); \
zval_ptr_dtor(&garbage); \
} while (0)

#define ZEND_TRY_ASSIGN_FALSE(zv) \
Expand All @@ -1144,8 +1148,10 @@ ZEND_API zend_result zend_try_assign_typed_ref_zval_ex(zend_reference *ref, zval
} \
_zv = &ref->val; \
} \
zval_ptr_dtor(_zv); \
zval garbage; \
ZVAL_COPY_VALUE(&garbage, _zv); \
ZVAL_TRUE(_zv); \
zval_ptr_dtor(&garbage); \
} while (0)

#define ZEND_TRY_ASSIGN_TRUE(zv) \
Expand All @@ -1166,8 +1172,10 @@ ZEND_API zend_result zend_try_assign_typed_ref_zval_ex(zend_reference *ref, zval
} \
_zv = &ref->val; \
} \
zval_ptr_dtor(_zv); \
zval garbage; \
ZVAL_COPY_VALUE(&garbage, _zv); \
ZVAL_BOOL(_zv, bval); \
zval_ptr_dtor(&garbage); \
} while (0)

#define ZEND_TRY_ASSIGN_BOOL(zv, bval) \
Expand All @@ -1188,8 +1196,10 @@ ZEND_API zend_result zend_try_assign_typed_ref_zval_ex(zend_reference *ref, zval
} \
_zv = &ref->val; \
} \
zval_ptr_dtor(_zv); \
zval garbage; \
ZVAL_COPY_VALUE(&garbage, _zv); \
ZVAL_LONG(_zv, lval); \
zval_ptr_dtor(&garbage); \
} while (0)

#define ZEND_TRY_ASSIGN_LONG(zv, lval) \
Expand All @@ -1210,8 +1220,10 @@ ZEND_API zend_result zend_try_assign_typed_ref_zval_ex(zend_reference *ref, zval
} \
_zv = &ref->val; \
} \
zval_ptr_dtor(_zv); \
zval garbage; \
ZVAL_COPY_VALUE(&garbage, _zv); \
ZVAL_DOUBLE(_zv, dval); \
zval_ptr_dtor(&garbage); \
} while (0)

#define ZEND_TRY_ASSIGN_DOUBLE(zv, dval) \
Expand All @@ -1232,8 +1244,10 @@ ZEND_API zend_result zend_try_assign_typed_ref_zval_ex(zend_reference *ref, zval
} \
_zv = &ref->val; \
} \
zval_ptr_dtor(_zv); \
zval garbage; \
ZVAL_COPY_VALUE(&garbage, _zv); \
ZVAL_EMPTY_STRING(_zv); \
zval_ptr_dtor(&garbage); \
} while (0)

#define ZEND_TRY_ASSIGN_EMPTY_STRING(zv) \
Expand All @@ -1254,8 +1268,10 @@ ZEND_API zend_result zend_try_assign_typed_ref_zval_ex(zend_reference *ref, zval
} \
_zv = &ref->val; \
} \
zval_ptr_dtor(_zv); \
zval garbage; \
ZVAL_COPY_VALUE(&garbage, _zv); \
ZVAL_STR(_zv, str); \
zval_ptr_dtor(&garbage); \
} while (0)

#define ZEND_TRY_ASSIGN_STR(zv, str) \
Expand All @@ -1276,8 +1292,10 @@ ZEND_API zend_result zend_try_assign_typed_ref_zval_ex(zend_reference *ref, zval
} \
_zv = &ref->val; \
} \
zval_ptr_dtor(_zv); \
zval garbage; \
ZVAL_COPY_VALUE(&garbage, _zv); \
ZVAL_NEW_STR(_zv, str); \
zval_ptr_dtor(&garbage); \
} while (0)

#define ZEND_TRY_ASSIGN_NEW_STR(zv, str) \
Expand All @@ -1298,8 +1316,10 @@ ZEND_API zend_result zend_try_assign_typed_ref_zval_ex(zend_reference *ref, zval
} \
_zv = &ref->val; \
} \
zval_ptr_dtor(_zv); \
zval garbage; \
ZVAL_COPY_VALUE(&garbage, _zv); \
ZVAL_STRING(_zv, string); \
zval_ptr_dtor(&garbage); \
} while (0)

#define ZEND_TRY_ASSIGN_STRING(zv, string) \
Expand All @@ -1320,8 +1340,10 @@ ZEND_API zend_result zend_try_assign_typed_ref_zval_ex(zend_reference *ref, zval
} \
_zv = &ref->val; \
} \
zval_ptr_dtor(_zv); \
zval garbage; \
ZVAL_COPY_VALUE(&garbage, _zv); \
ZVAL_STRINGL(_zv, string, len); \
zval_ptr_dtor(&garbage); \
} while (0)

#define ZEND_TRY_ASSIGN_STRINGL(zv, string, len) \
Expand All @@ -1342,8 +1364,10 @@ ZEND_API zend_result zend_try_assign_typed_ref_zval_ex(zend_reference *ref, zval
} \
_zv = &ref->val; \
} \
zval_ptr_dtor(_zv); \
zval garbage; \
ZVAL_COPY_VALUE(&garbage, _zv); \
ZVAL_ARR(_zv, arr); \
zval_ptr_dtor(&garbage); \
} while (0)

#define ZEND_TRY_ASSIGN_ARR(zv, arr) \
Expand All @@ -1364,8 +1388,10 @@ ZEND_API zend_result zend_try_assign_typed_ref_zval_ex(zend_reference *ref, zval
} \
_zv = &ref->val; \
} \
zval_ptr_dtor(_zv); \
zval garbage; \
ZVAL_COPY_VALUE(&garbage, _zv); \
ZVAL_RES(_zv, res); \
zval_ptr_dtor(&garbage); \
} while (0)

#define ZEND_TRY_ASSIGN_RES(zv, res) \
Expand All @@ -1386,8 +1412,10 @@ ZEND_API zend_result zend_try_assign_typed_ref_zval_ex(zend_reference *ref, zval
} \
_zv = &ref->val; \
} \
zval_ptr_dtor(_zv); \
zval garbage; \
ZVAL_COPY_VALUE(&garbage, _zv); \
ZVAL_COPY_VALUE(_zv, other_zv); \
zval_ptr_dtor(&garbage); \
} while (0)

#define ZEND_TRY_ASSIGN_TMP(zv, other_zv) \
Expand All @@ -1408,8 +1436,10 @@ ZEND_API zend_result zend_try_assign_typed_ref_zval_ex(zend_reference *ref, zval
} \
_zv = &ref->val; \
} \
zval_ptr_dtor(_zv); \
zval garbage; \
ZVAL_COPY_VALUE(&garbage, _zv); \
ZVAL_COPY_VALUE(_zv, other_zv); \
zval_ptr_dtor(&garbage); \
} while (0)

#define ZEND_TRY_ASSIGN_VALUE(zv, other_zv) \
Expand Down Expand Up @@ -1440,8 +1470,10 @@ ZEND_API zend_result zend_try_assign_typed_ref_zval_ex(zend_reference *ref, zval
} \
_zv = &ref->val; \
} \
zval_ptr_dtor(_zv); \
zval garbage; \
ZVAL_COPY_VALUE(&garbage, _zv); \
ZVAL_COPY_VALUE(_zv, other_zv); \
zval_ptr_dtor(&garbage); \
} while (0)

#define ZEND_TRY_ASSIGN_VALUE_EX(zv, other_zv, strict) \
Expand Down

0 comments on commit 9ab9dc2

Please sign in to comment.