Skip to content

Fix GH-22678: array_multisort() use-after-free on mutating comparator#152

Closed
iliaal wants to merge 1 commit into
PHP-8.4from
fix/gh-22678-multisort-uaf
Closed

Fix GH-22678: array_multisort() use-after-free on mutating comparator#152
iliaal wants to merge 1 commit into
PHP-8.4from
fix/gh-22678-multisort-uaf

Conversation

@iliaal

@iliaal iliaal commented Jul 10, 2026

Copy link
Copy Markdown
Owner

array_multisort() borrows each input array's buckets without a refcount, then runs the comparator; under SORT_STRING that reaches Stringable::__toString(), so a callback that unsets or reassigns the array frees its backing store and elements mid-sort (use-after-free in the comparator, and a write-back through the freed table in the restructure). Holding a reference on each input HashTable for the duration of the sort fixes it, mirroring zend_array_sort_ex() (phpGH-16648); HT_ALLOW_COW_VIOLATION lets the in-place restructure repack the still-referenced table. Fixes php#22678

array_multisort() snapshotted each input array's buckets without holding a
reference, then ran a comparator that under SORT_STRING invokes
Stringable::__toString(); a callback that unset or reassigned the array freed
its backing store and elements mid-sort, a use-after-free read in the
comparator and a write-back through the freed table during the restructure.
Hold a reference on each input HashTable for the duration of the sort and
restructure the cached tables, mirroring zend_array_sort_ex() (phpGH-16648).
HT_ALLOW_COW_VIOLATION allows the in-place repack under the held reference.

Fixes phpGH-22678
@iliaal

iliaal commented Jul 10, 2026

Copy link
Copy Markdown
Owner Author

Promoted upstream: php#22680

@iliaal iliaal closed this Jul 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant