Fix possible double-free with hooks on internal methods inherited by user classes #2372
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
Doing the due diligence whether I can reuse nNumOfElements in the HashTable, to increase and decrease it, so that all checks for zend_hash_num_elements() == 0 only are true when neither internal duplicates exist, nor actual hooks exist, I missed the tiny detail, that, while all direct usages of nNumOfElements were safe, there was an usage of nNumOfElements in the HT_IS_WITHOUT_HOLES() macro, checking whether nNumOfElements == nNumUsed.
Thus, when there were two hooks, one later removed, and one class inheriting the internal method, nNumOfElements happened to be equal to nNumUsed in shutdown. During hash destruction the smart Zend code would check this and unconditionally iterate over all elements of the array, skipping IS_UNDEF checks.
Eventually leading to a double free.
As a saving grace, this double free generally happened very late in the shutdown sequence, so the memory corruption would usually not surface...
Readiness checklist
Reviewer checklist