Prevent Lua VM re-entry through JIT trace. #1165
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
TL;DR:
I'd like to upstream the patch (tarantool/luajit@4f4fd9eb) implemented almost 4 years ago to prevent Tarantool crashes caused by FFI machinery misuse (see tarantool/tarantool#4427 for more info), that is widely exploited in Tarantool sources. The Tarantool issue has been fixed, and no related crashes has occurred since the patch has been applied to the long-term branches within our LuaJIT fork. Hence, I decided to try landing this patch to the upstream considering the fact #1066 is finally aboard.
@MikePall, I'm OK if you don't want to apply the changeset; at least the misuse will be described here and someone exploiting any FFI holes (I'm completely against this) will know the symptoms and the pill.
Description
JIT recording semantics assumes FFI calls are leaf regarding the LuaJIT VM: if the execution exited Lua world through FFI machinery it is not re-entering Lua world again.
However, there is a way to break this assumption via FFI: one can re-enter LuaJIT VM via Lua C API, used within the particular C routine called via FFI. As a result the following host stack mix is created:
This sort of re-entry is not supported by LuaJIT tracing compiler. @mraleph named such kind of the call stack an "FFI sandwich" in the tarantool/tarantool#4427.
This changeset introduces the mechanism for Lua-C API callbacks similar to the one implemented for Lua-FFI: trace recording is aborted when the execution re-enters LuaJIT VM. If the re-enter is detected while running the particular mcode, the runtime finishes its execution with
EXIT_FAILURE
code and calls the panic routine prior to the exit.The patch slightly differs from the one committed via tarantool/luajit@4f4fd9eb, but all the changes are cosmetic to make the original idea more clear.
How to reproduce the bug:
libsandwich.c
sandwich.lua
As a result of the patch the last command ends the following way
Co-authored-by: Vyacheslav Egorov vegorov@google.com
Co-authored-by: Sergey Ostanevich sergos@tarantool.org
Signed-off-by: Igor Munkin imun@cpan.org