-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Implement GH-9826: Make class_alias() work with internal classes #10483
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
Conversation
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.
I haven't analyzed this in detail so my suggestion might not make sense.
Reading Nikitas comment it sounds like he suggested not refcounting aliases at all. Class aliases seem to be the only place where refcount
is currently incremented for classes so I'm not sure if refcounting would even have a purpose anymore at that point.
init_executor
sets EG(persistent_classes_count)
and shutdown_executor
will destroy all classes that were allocated after that point. Since we can't persistently alias a request-allocated class for obvious reasons it doesn't seem like refcounting is necessary. We'll either:
- persistently alias a persistent class
- temporarily (per request) alias a persistent class
- temporarily (per request) alias a temporary (per request) class
None of those can cause a use-after-free (if we skip IS_ALIAS_PTR
during class destruction, that is). Thus, we might be able to avoid IS_INTERNAL_CLASS_REQUEST_ALIAS_PTR
and just skip refcounting for all IS_ALIAS_PTR
.
I also noticed that there are a couple of |
Right, your suggestion makes sense, quite a bit more sense than my current solution :p |
Yeah, that makes way more sense than what I suggested 🙂 |
Pushed the changes with your suggestion applied. |
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.
Thank you! Apart from this small optimization this looks good to me.
@nielsdos I checked the failure locally, it looks like --- a/Zend/zend_opcode.c
+++ b/Zend/zend_opcode.c
@@ -524,7 +524,7 @@ void zend_class_add_ref(zval *zv)
{
zend_class_entry *ce = Z_PTR_P(zv);
- if (!(ce->ce_flags & ZEND_ACC_IMMUTABLE)) {
+ if (Z_TYPE_P(zv) != IS_ALIAS_PTR && !(ce->ce_flags & ZEND_ACC_IMMUTABLE)) {
ce->refcount++;
}
}
|
Thank you! I fixed it. Feel free to add your Co-authored-by tag btw if you end up merging this, because you helped out quite alot with this PR :) |
Something very weird went wrong with the CI... It claims there was a compile error on x32:
But that code doesn't exist in this branch?! Seems like caching gone wrong or something like that? |
Hmm we merged ccache for CI recently. Maybe that's related. I'll check later. |
@nielsdos This was unrelated to ccache but fixed. Could you rebase this onto master when you have time? Thank you! |
Alright, rebased. Let's see if the tests pass now :) |
201b28b
to
799d05b
Compare
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.
@dstogov Does this look reasonable to you?
From what I can see, zend_class_entry.refcount
was previously just used to skip class destruction for aliases, and as an optimization to skip the alias check (comparing class names) for classes that aren't aliased. Both of those go away with this PR. We could remove refcount
altogether now, as it's never increased anymore. Does that sound ok to you?
This looks fine. I'm only not sure in
It's still used in |
We can't increase the refcount of internal classes during request time. To work around this problem we simply don't refcount aliases anymore and add a check in the destruction to skip aliases entirely. There were also some checks which checked for an alias implicitly by comparing the refcount, these have been replaced by checking the type of the zval instead.
799d05b
to
436f00b
Compare
Applied the requested changes, thanks. |
Credits to Nikita because he basically described how to implement this in the issue comment.
We can't increase the refcount of internal classes during request time.
To work around this problem we simply don't refcount aliases anymore and
add a check in the destruction to skip aliases entirely.
There were also some checks which checked for an alias implicitly by
comparing the refcount, these have been replaced by checking the type of
the zval instead.