-
Notifications
You must be signed in to change notification settings - Fork 7.7k
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
Delay notice emission until end of opcode #6903
Conversation
This is a prototype for fixing a long-standing source of interrupt vulnerabilities: A notice is emitted during execution of an opcode, resulting in an error handling being run. The error handler modifies some data structure the opcode is working on, resulting in UAF or other memory corruption. The idea here is to instead collect notices and only process them after the opcode. This is implemented similarly to exception handling, by switching to a ZEND_HANDLE_DELAYED_ERROR opcode, which will then switch back to the normal opcode stream. Unfortunately, what this prototype implements is not sufficient. Opcodes that acquire direct (INDIRECT) references to zvals require that no interrupts occur between the producing and the consuming opcode. Chains of W/RW opcodes should be executed without interrupt. Currently, the notice is only delayed until after the first opcode, which still results in an illegal interrupt (bug78598.phpt shows a UAF with this change). I'm not sure how to best handle that issue.
This is needed by both fibers and opcache (and GH-6903 also uses it), so make it a common structure that can be used by any functionality storing warnings/errors.
Which opcodes require that there are no interruptions? Is there a flag set on them in |
The |
Are the |
@trowski It's not possible to modify the opcode stream (it is usually in immutable in SHM). The only thing we can do is change the pointer to the currently executed instruction. |
Ah yes, I assumed there was a reason the simple solution wouldn't work, thanks for the explanation. You could create a temporary op_array that is pushed on the stack containing only the uninterruptible opcodes and the error handler, then free the temp op_array either in the error handler or in another opcode. I'm sure you thought of that too and there are complications to that solution. 😆 |
I'm looking into a solution for this. One approach may be to set One issue is that There may be more issues that I haven't discovered yet. |
I think this outdated PR should be closed. |
This is a prototype for fixing a long-standing source of interrupt
vulnerabilities: A notice is emitted during execution of an opcode,
resulting in an error handling being run. The error handler modifies
some data structure the opcode is working on, resulting in UAF or
other memory corruption.
The idea here is to instead collect notices and only process them
after the opcode. This is implemented similarly to exception
handling, by switching to a ZEND_HANDLE_DELAYED_ERROR opcode,
which will then switch back to the normal opcode stream.
Unfortunately, what this prototype implements is not sufficient.
Opcodes that acquire direct (INDIRECT) references to zvals require
that no interrupts occur between the producing and the consuming
opcode. Chains of W/RW opcodes should be executed without interrupt.
Currently, the notice is only delayed until after the first opcode,
which still results in an illegal interrupt (bug78598.phpt shows
a UAF with this change).
I'm not sure how to best handle that issue.