# Use After Free in sortWithSortKeys()

Use-after-free in PHP 7 Collator::sortWithSortKeys() where freed array element pointers are reinserted into a new array, causing dangling-pointer dereference and memory corruption.

- Payout: $1,000
- Severity: high
- Program: Internet Bug Bounty
- Credited: libnex
- Disclosed: 2016-01-20
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/109175
- Library page: https://bugbountylibrary.com/r/h1%3A109175
- Tags: domain:oss impact:dos kind:bounty platform:hackerone sev:high tech:php technique:source-review vuln:dos vuln:memory-corruption

**Target:** ext/intl Collator::sortWithSortKeys()
**Root cause:** sortKeyIndxBuf[].zstr stores pointers to array elements; the array is destroyed via zval_ptr_dtor freeing those elements, then the dangling pointers are reinserted into a new array and dereferenced via Z_TRY_ADDREF_P.
**Steps:**
1. Call `Collator::sortWithSortKeys($array)` with an array of ~0xbb elements
2. Function stores each element pointer in sortKeyIndxBuf[sortKeyCount].zstr (line 493)
3. Array destroyed via `zval_ptr_dtor(array)` (line 508), freeing elements; pointers now dangle
4. `array_init(array)` reinitializes (line 510)
5. Dangling pointers inserted via `zend_hash_next_index_insert` (line 515)
6. Hashtable resize reallocates memory overlapping a dangling pointer
7. `Z_TRY_ADDREF_P(sortKeyIndxBuf[j].zstr)` (line 514) dereferences corrupted zval -> SIGSEGV
**How found:** Code review of collator_sort.c tracking pointer lifetime: noticed sortKeyIndxBuf held raw pointers to array elements that were freed by zval_ptr_dtor before being reinserted into a fresh array.
**Exploitation:** Crash demonstrated via null-pointer dereference in zval_addref_p; PHP dev noted it could be exploitable if sortable data is user-controlled, but no full exploitation chain shown.
**Insight:** When auditing C extensions, trace raw zval pointers stored in local buffers across zval_ptr_dtor calls; any pointer surviving a dtor and later reinserted/dereferenced is a UAF. Heap-grooming via hashtable resize can turn the dangling pointer into a controlled corrupted zval.
