Skip to content

Commit af9a4a7

Browse files
committed
Fix GH-12186: segfault copying/cloning a finalized HashContext
Closes #12186
1 parent 8f8f31a commit af9a4a7

File tree

4 files changed

+42
-2
lines changed

4 files changed

+42
-2
lines changed

ext/hash/hash.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,7 @@ PHP_FUNCTION(hash_init)
681681

682682
#define PHP_HASHCONTEXT_VERIFY(hash) { \
683683
if (!hash->context) { \
684-
zend_argument_type_error(1, "must be a valid Hash Context resource"); \
684+
zend_argument_type_error(1, "must be a valid, non-finalized HashContext"); \
685685
RETURN_THROWS(); \
686686
} \
687687
}
@@ -838,11 +838,15 @@ PHP_FUNCTION(hash_final)
838838
PHP_FUNCTION(hash_copy)
839839
{
840840
zval *zhash;
841+
php_hashcontext_object *context;
841842

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

847+
context = php_hashcontext_from_object(Z_OBJ_P(zhash));
848+
PHP_HASHCONTEXT_VERIFY(context);
849+
846850
RETVAL_OBJ(Z_OBJ_HANDLER_P(zhash, clone_obj)(Z_OBJ_P(zhash)));
847851

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

1402+
if (!oldobj->context) {
1403+
zend_throw_exception(zend_ce_value_error, "Cannot clone a finalized HashContext", 0);
1404+
return &newobj->std;
1405+
}
1406+
13981407
zend_objects_clone_members(znew, zobj);
13991408

14001409
newobj->ops = oldobj->ops;

ext/hash/tests/gh12186_1.phpt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
Hash: bug #12186 - segfault in hash_copy() on a finalized context
3+
--FILE--
4+
<?php
5+
6+
$c = hash_init('sha1');
7+
hash_final($c);
8+
hash_copy($c);
9+
10+
?>
11+
--EXPECTF--
12+
Fatal error: Uncaught TypeError: hash_copy(): Argument #1 ($context) must be a valid, non-finalized HashContext in %s:5
13+
Stack trace:
14+
#0 %s(5): hash_copy(Object(HashContext))
15+
#1 {main}
16+
thrown in %s on line 5

ext/hash/tests/gh12186_2.phpt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
Hash: bug #12186 - segfault when cloning a finalized context
3+
--FILE--
4+
<?php
5+
6+
$c = hash_init('sha1');
7+
hash_final($c);
8+
clone $c;
9+
10+
?>
11+
--EXPECTF--
12+
Fatal error: Uncaught ValueError: Cannot clone a finalized HashContext in %s
13+
Stack trace:
14+
#0 {main}
15+
thrown in %s on line 5

ext/hash/tests/reuse.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ catch (\Error $e) {
1414

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

0 commit comments

Comments
 (0)