-
Notifications
You must be signed in to change notification settings - Fork 171
Prevent func_hash_counters underflow #91
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
- The 1 (third parameter) means "destroy the original zval after copying" - This transfers ownership completely to the return value - XHPROF_G(stats_count) becomes IS_UNDEF - During cleanup, the check if (Z_TYPE(XHPROF_G(stats_count)) != IS_UNDEF) fails - No double-free occurs
1. Ignored functions in PHP 8.0+ create entries with is_trace = 0 2. These entries skip hp_mode_common_beginfn() so the hash counter is never incremented 3. But hp_mode_hier_endfn_cb() was always decrementing the hash counter 4. This caused hash counter underflow, which could lead to memory corruption and segfaults
If a callback is found and executed, it calls zend_string_release(function_name) and returns trace_name. However, if no callback is found, it returns function_name directly without releasing it.
This reverts commit 7e06de7.
Fixes segmentation fault when the first function call in a request is an ignored function. Previously, the code assumed *(entries) was always non-NULL when creating entries for ignored functions, but this caused a NULL pointer dereference when profiling started with an ignored function. The fix adds a NULL check and uses the actual function name when entries is NULL, ensuring proper initialization of the entry stack even when the first call is ignored.
Sets p->name_hprof to NULL after releasing the string in hp_fast_free_hprof_entry() to prevent potential double-free errors if the same entry is processed multiple times or reused from the free list with stale pointer data
…emory" This reverts commit 5a6c4e6.
| callback = (hp_trace_callback*)zend_hash_find_ptr(XHPROF_G(trace_callbacks), function_name); | ||
| if (callback) { | ||
| trace_name = (*callback)(function_name, data); | ||
| } else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previously:
- If a callback is found, release function_name and return trace_name
- If no callback is found, return function_name directly without releasing it
| #if PHP_VERSION_ID >= 80000 | ||
| hp_entry_t *cur_entry = hp_fast_alloc_hprof_entry(); | ||
| (cur_entry)->name_hprof = zend_string_copy((*(entries))->name_hprof); | ||
| /* Check if entries is not NULL before dereferencing */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previously assumed *(entries) is always non-NULL when creating entries for ignored functions.
| #if PHP_VERSION_ID >= 80000 | ||
| if (top->is_trace == 0) { | ||
| XHPROF_G(func_hash_counters[top->hash_code])--; | ||
| /* For ignored functions, don't decrement hash counter since it was never incremented */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previously:
hp_mode_common_beginfn()was never called -> hash counter never incrementedhp_mode_hier_endfn_cb()was always decrementing the hash counter -> counter underflow
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello, this should only affect PHP 8.4?
Fixes #84, #90.