-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Resolve Inconsistency in zend_jit_return Between JIT and Non-JIT Engines #14841
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
base: PHP-8.2
Are you sure you want to change the base?
Conversation
I asked to the rest of the team if your PR would qualify as security fix (8.1 is EOL), if not then it would need to target PHP-8.2 instead. We shall see. |
Ah, I misread the contributing guide and version table. I'm happy to rebase on 8.2 |
Re-based to PHP-8.2 |
There was another small fix regarding parameters, In non-JIT mode, This caused the test to display different return values for JIT and non-JIT modes, while still producing the expected final result outside the observer. Data comparison inside BEFORE 2nd Fix:
JIT:
execute_data->return_value: ptr:d0216080 zval.value.lval:41b3cf90
retval: ptr:421e0830 zval.value.lval:41b3cf90
NON:
execute_data->return_value: ptr:fc016080 zval.value.lval:4065bf90
retval: ptr:fc016080 zval.value.lval:4065bf90
AFTER 2nd Fix:
JIT:
execute_data->return_value: ptr:b5016080 zval.value.lval:6aa32c78
retval: ptr:b5016080 zval.value.lval:6aa32c78
NON:
execute_data->return_value: ptr:c1616080 zval.value.lval:20232c78
retval: ptr:c1616080 zval.value.lval:20232c78 |
@segrax Thank you for your PR! Note that Dmitry, who is responsible for the JIT, is on vacation for the next two weeks. So it might take a minute for you to get a proper review. |
ext/opcache/jit/zend_jit_arm64.dasc
Outdated
if (return_value_used != 0) { | ||
if (opline->op1_type == IS_CONST) { |
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.
Can you please try to minimize the patch, avoiding indentation changes. e.g.
if (return_value_used == 0) {
/* pass */
} else if (opline->op1_type == IS_CONST) {
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.
Yep, done
cc: @bwoebi |
Thanks! @bwoebi please check the observer related behavior and merge this. |
I'm confused, like the patch seems to be only concerned with the pass case and IS_CONST and IS_TMP_VAR? Reading the IS_CV case, isn't it sending the pointer to the CV rather than the ret_addr to zend_observer_fcall_end? I must admit I don't really understand what the
part is doing. At least - IF the value is returned - it's always supposed to be the return address, not sometimes op1_addr. Like, wouldn't this be correct:
Maybe @dstogov can help here? |
The last @bwoebi suggestion seems right! |
@bwoebi yeah, currently it only fixes the issue i found while working with the OpenTelemetry extension, there is likely the same issue with the other types, but too be honest, i wasn't entirely sure what everything here was doing. Figured I would submit what I had, and work from there
It seems this change causes a test failure, but only in the debug builds (my local build is fine, but I also haven't checked what flags are being used in the debug pipeline builds).
|
@segrax did you see ext/opcache/tests/jit/gh13772.phpt test failure? |
Hey @dstogov, Yeah, I did see the failure, it came from the change in the last recommendation, but it seems to have caused the test failure, So was waiting to hear back from @bwoebi before reverting it or making any further changes
|
OK. ping we when you'll need the next round of my review. |
Hey @dstogov, I've reverted that last change |
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.
This shouldn't change anything for JIT without observer.
I don't care about observer.
@bwoebi if this is right for you please take care about merging and porting to master.
This resolves an inconsistency in both the x86 and ARM64 implementation of
zend_jit_return
between the JIT and non-JIT engines (op: ZEND_RETURN_SPEC_OBSERVER).Issue
zend_observer_fcall_end
is invoked after the returnedzval
is copied intoexecute_data->return_value
.zend_observer_fcall_end
is invoked before the returnedzval
is copied.Behaviour
Extensions using the value in
execute_data->return_value
behave differently in JIT mode, which can lead to incorrect readings, and/or segfaults if values are being modified.Affects
PHP 8.1 to 8.4 (issue is present in the new JIT)
Tests
I've extended the zend_test extension to allow hooks to be executed from calls to zend_observer_fcall_end, and added a test which modifies the return value