Skip to content

Commit

Permalink
Fix phpGH-12186: segfault copying/cloning a finalized HashContext
Browse files Browse the repository at this point in the history
Closes php#12186
  • Loading branch information
MaxSem committed Sep 12, 2023
1 parent 8f8f31a commit 95cd40c
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 2 deletions.
3 changes: 3 additions & 0 deletions Zend/zend_vm_execute.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 10 additions & 1 deletion ext/hash/hash.c
Expand Up @@ -681,7 +681,7 @@ PHP_FUNCTION(hash_init)

#define PHP_HASHCONTEXT_VERIFY(hash) { \
if (!hash->context) { \
zend_argument_type_error(1, "must be a valid Hash Context resource"); \
zend_argument_type_error(1, "must be a valid, non-finalized HashContext"); \
RETURN_THROWS(); \
} \
}
Expand Down Expand Up @@ -838,11 +838,15 @@ PHP_FUNCTION(hash_final)
PHP_FUNCTION(hash_copy)
{
zval *zhash;
php_hashcontext_object *context;

if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &zhash, php_hashcontext_ce) == FAILURE) {
RETURN_THROWS();
}

context = php_hashcontext_from_object(Z_OBJ_P(zhash));
PHP_HASHCONTEXT_VERIFY(context);

RETVAL_OBJ(Z_OBJ_HANDLER_P(zhash, clone_obj)(Z_OBJ_P(zhash)));

if (php_hashcontext_from_object(Z_OBJ_P(return_value))->context == NULL) {
Expand Down Expand Up @@ -1395,6 +1399,11 @@ static zend_object *php_hashcontext_clone(zend_object *zobj) {
zend_object *znew = php_hashcontext_create(zobj->ce);
php_hashcontext_object *newobj = php_hashcontext_from_object(znew);

if (!oldobj->context) {
zend_throw_exception(zend_ce_value_error, "Cannot clone a finalized HashContext", 0);
return NULL;
}

zend_objects_clone_members(znew, zobj);

newobj->ops = oldobj->ops;
Expand Down
16 changes: 16 additions & 0 deletions ext/hash/tests/gh12186_1.phpt
@@ -0,0 +1,16 @@
--TEST--
Hash: bug #12186 - segfault in hash_copy() on a finalized context
--FILE--
<?php

$c = hash_init('sha1');
hash_final($c);
hash_copy($c);

?>
--EXPECTF--
Fatal error: Uncaught TypeError: hash_copy(): Argument #1 ($context) must be a valid, non-finalized HashContext in %s:5
Stack trace:
#0 %s(5): hash_copy(Object(HashContext))
#1 {main}
thrown in %s on line 5
15 changes: 15 additions & 0 deletions ext/hash/tests/gh12186_2.phpt
@@ -0,0 +1,15 @@
--TEST--
Hash: bug #12186 - segfault when cloning a finalized context
--FILE--
<?php

$c = hash_init('sha1');
hash_final($c);
clone $c;

?>
--EXPECTF--
Fatal error: Uncaught ValueError: Cannot clone a finalized HashContext in %s
Stack trace:
#0 {main}
thrown in %s on line 5
2 changes: 1 addition & 1 deletion ext/hash/tests/reuse.phpt
Expand Up @@ -14,4 +14,4 @@ catch (\Error $e) {

?>
--EXPECT--
hash_update(): Argument #1 ($context) must be a valid Hash Context resource
hash_update(): Argument #1 ($context) must be a valid, non-finalized HashContext

0 comments on commit 95cd40c

Please sign in to comment.