Fix GH-21831: Defer removals during SplObjectStorage::removeAllExcept()#21835
Fix GH-21831: Defer removals during SplObjectStorage::removeAllExcept()#21835prateekbhujel wants to merge 2 commits intophp:masterfrom
Conversation
Girgias
left a comment
There was a problem hiding this comment.
I'm not sure I like this approach, but not sure how what I would want the behaviour to be is achievable.
Ideally one shouldn't be able to mess with the state from the getHash() method, as it's meant to be somewhat of a pure function.
|
Yeah, I agree with that.
|
|
I think it would be cleaner to just change what getHash() is allowed to do, considering you are already targeting master and this seems very artificial so not sure it's worth backporting |
|
I tried that direction locally. The tricky part is that master already includes the recent concurrent-deletion coverage added in 43a4f91 (GH-21443), and once getHash() starts rejecting mutation those cases begin to fail. So that turns it into a behavior change, not just a cleanup around this UAF. That’s why I kept this one narrow: fix the use-after-free in removeAllExcept() without changing the current getHash() re-entrancy behavior. |
Fixes GH-21831.
SplObjectStorage::removeAllExcept() may detach from the storage while a custom getHash() implementation is still able to re-enter and mutate that same storage.
Defer those removals until after the scan finishes so the iteration stays stable.