mirror of
https://github.com/php/php-src.git
synced 2024-11-23 09:54:15 +08:00
Fix GH-15210: phpdbg_print_changed_zvals working on a real copy instead.
Close GH-15229
This commit is contained in:
parent
a6c547d1dd
commit
9aeb6761b5
1
NEWS
1
NEWS
@ -47,6 +47,7 @@ PHP NEWS
|
||||
with libedit/readline). (Peter Kokot)
|
||||
. Fixed bug GH-15268 (heap buffer overflow in phpdbg
|
||||
(zend_hash_num_elements() Zend/zend_hash.h)). (nielsdos)
|
||||
. Fixed bug GH-15210 use-after-free on watchpoint allocations. (nielsdos)
|
||||
|
||||
- Soap:
|
||||
. Fixed bug #55639 (Digest autentication dont work). (nielsdos)
|
||||
|
@ -254,6 +254,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg)
|
||||
HashTable watch_recreation; /* watch elements pending recreation of their respective watchpoints */
|
||||
HashTable watch_free; /* pointers to watch for being freed */
|
||||
HashTable *watchlist_mem; /* triggered watchpoints */
|
||||
HashTable *original_watchlist_mem; /* the original allocation for watchlist_mem, used when watchlist_mem has changed temporarily */
|
||||
HashTable *watchlist_mem_backup; /* triggered watchpoints backup table while iterating over it */
|
||||
bool watchpoint_hit; /* a watchpoint was hit */
|
||||
void (*original_free_function)(void *); /* the original AG(mm_heap)->_free function */
|
||||
|
@ -1551,6 +1551,8 @@ int phpdbg_interactive(bool allow_async_unsafe, char *input) /* {{{ */
|
||||
ret = phpdbg_stack_execute(&stack, allow_async_unsafe);
|
||||
} zend_catch {
|
||||
phpdbg_stack_free(&stack);
|
||||
phpdbg_destroy_input(&input);
|
||||
/* TODO: should use proper unwinding instead of bailing out */
|
||||
zend_bailout();
|
||||
} zend_end_try();
|
||||
|
||||
|
@ -516,7 +516,9 @@ phpdbg_watch_element *phpdbg_add_watch_element(phpdbg_watchpoint_t *watch, phpdb
|
||||
phpdbg_watch_element *old_element;
|
||||
watch = res->ptr;
|
||||
if ((old_element = zend_hash_find_ptr(&watch->elements, element->str))) {
|
||||
phpdbg_free_watch_element(element);
|
||||
if (element != old_element) {
|
||||
phpdbg_free_watch_element(element);
|
||||
}
|
||||
return old_element;
|
||||
}
|
||||
}
|
||||
@ -1471,6 +1473,7 @@ void phpdbg_setup_watchpoints(void) {
|
||||
|
||||
/* put these on a separate page, to avoid conflicts with other memory */
|
||||
PHPDBG_G(watchlist_mem) = malloc(phpdbg_pagesize > sizeof(HashTable) ? phpdbg_pagesize : sizeof(HashTable));
|
||||
PHPDBG_G(original_watchlist_mem) = PHPDBG_G(watchlist_mem);
|
||||
zend_hash_init(PHPDBG_G(watchlist_mem), phpdbg_pagesize / (sizeof(Bucket) + sizeof(uint32_t)), NULL, NULL, 1);
|
||||
PHPDBG_G(watchlist_mem_backup) = malloc(phpdbg_pagesize > sizeof(HashTable) ? phpdbg_pagesize : sizeof(HashTable));
|
||||
zend_hash_init(PHPDBG_G(watchlist_mem_backup), phpdbg_pagesize / (sizeof(Bucket) + sizeof(uint32_t)), NULL, NULL, 1);
|
||||
@ -1517,8 +1520,8 @@ void phpdbg_destroy_watchpoints(void) {
|
||||
zend_hash_destroy(&PHPDBG_G(watch_recreation));
|
||||
zend_hash_destroy(&PHPDBG_G(watch_free));
|
||||
zend_hash_destroy(&PHPDBG_G(watch_collisions));
|
||||
zend_hash_destroy(PHPDBG_G(watchlist_mem));
|
||||
free(PHPDBG_G(watchlist_mem));
|
||||
zend_hash_destroy(PHPDBG_G(original_watchlist_mem));
|
||||
free(PHPDBG_G(original_watchlist_mem));
|
||||
zend_hash_destroy(PHPDBG_G(watchlist_mem_backup));
|
||||
free(PHPDBG_G(watchlist_mem_backup));
|
||||
}
|
||||
|
30
sapi/phpdbg/tests/gh15210_001.phpt
Normal file
30
sapi/phpdbg/tests/gh15210_001.phpt
Normal file
@ -0,0 +1,30 @@
|
||||
--TEST--
|
||||
GH-15210 use after free after continue
|
||||
--PHPDBG--
|
||||
b 4
|
||||
r
|
||||
w $a[0]
|
||||
c
|
||||
q
|
||||
--FILE--
|
||||
<?php
|
||||
header_register_callback(function() { echo "sent";});
|
||||
$a = [0];
|
||||
$a[0] = 1;
|
||||
?>
|
||||
--EXPECTF--
|
||||
[Successful compilation of %s]
|
||||
prompt> [Breakpoint #0 added at %s:%d]
|
||||
prompt> [Breakpoint #0 at %s:%d, hits: 1]
|
||||
>00004: $a[0] = 1;
|
||||
00005: ?>
|
||||
00006:
|
||||
prompt> [Added watchpoint #0 for $a[0]]
|
||||
prompt> [Breaking on watchpoint $a[0]]
|
||||
Old value: [Breaking on watchpoint $a[0]]
|
||||
Old value: 0
|
||||
New value: 1
|
||||
>00002: header_register_callback(function() { echo "sent";});
|
||||
00003: $a = [0];
|
||||
00004: $a[0] = 1;
|
||||
prompt> [$a[0] has been removed, removing watchpoint]
|
36
sapi/phpdbg/tests/gh15210_002.phpt
Normal file
36
sapi/phpdbg/tests/gh15210_002.phpt
Normal file
@ -0,0 +1,36 @@
|
||||
--TEST--
|
||||
GH-15210 use after free after continue
|
||||
--PHPDBG--
|
||||
b 4
|
||||
r
|
||||
w $a[0]
|
||||
c
|
||||
c
|
||||
q
|
||||
--FILE--
|
||||
<?php
|
||||
header_register_callback(function() { echo "sent";});
|
||||
$a = [0];
|
||||
$a[0] = 1;
|
||||
?>
|
||||
--EXPECTF--
|
||||
[Successful compilation of %s]
|
||||
prompt> [Breakpoint #0 added at %s:%d]
|
||||
prompt> [Breakpoint #0 at %s:%d, hits: 1]
|
||||
>00004: $a[0] = 1;
|
||||
00005: ?>
|
||||
00006:
|
||||
prompt> [Added watchpoint #0 for $a[0]]
|
||||
prompt> [Breaking on watchpoint $a[0]]
|
||||
Old value: [Breaking on watchpoint $a[0]]
|
||||
Old value: 0
|
||||
New value: 1
|
||||
>00002: header_register_callback(function() { echo "sent";});
|
||||
00003: $a = [0];
|
||||
00004: $a[0] = 1;
|
||||
prompt> sent0
|
||||
New value: 1
|
||||
|
||||
[$a[0] has been removed, removing watchpoint]
|
||||
[Script ended normally]
|
||||
prompt>
|
Loading…
Reference in New Issue
Block a user