summaryrefslogtreecommitdiffstats
path: root/module/lua/lstate.c
diff options
context:
space:
mode:
authorMatthew Ahrens <[email protected]>2020-07-27 16:11:47 -0700
committerGitHub <[email protected]>2020-07-27 16:11:47 -0700
commit3eabed74c0fca5dd9f96d2cca13c4a1a16d5c094 (patch)
treedac524f95cbf222459729fa6af23b2df2d39ac85 /module/lua/lstate.c
parente64cc4954c7862db6a6b4dc978a091ebc3f870da (diff)
Fix lua stack overflow on recursive call to gsub()
The `zfs program` subcommand invokes a LUA interpreter to run ZFS "channel programs". This interpreter runs in a constrained environment, with defined memory limits. The LUA stack (used for LUA functions that call each other) is allocated in the kernel's heap, and is limited by the `-m MEMORY-LIMIT` flag and the `zfs_lua_max_memlimit` module parameter. The C stack is used by certain LUA features that are implemented in C. The C stack is limited by `LUAI_MAXCCALLS=20`, which limits call depth. Some LUA C calls use more stack space than others, and `gsub()` uses an unusually large amount. With a programming trick, it can be invoked recursively using the C stack (rather than the LUA stack). This overflows the 16KB Linux kernel stack after about 11 iterations, less than the limit of 20. One solution would be to decrease `LUAI_MAXCCALLS`. This could be made to work, but it has a few drawbacks: 1. The existing test suite does not pass with `LUAI_MAXCCALLS=10`. 2. There may be other LUA functions that use a lot of stack space, and the stack space may change depending on compiler version and options. This commit addresses the problem by adding a new limit on the amount of free space (in bytes) remaining on the C stack while running the LUA interpreter: `LUAI_MINCSTACK=4096`. If there is less than this amount of stack space remaining, a LUA runtime error is generated. Reviewed-by: George Wilson <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Ryan Moeller <[email protected]> Reviewed-by: Allan Jude <[email protected]> Reviewed-by: Serapheim Dimitropoulos <[email protected]> Signed-off-by: Matthew Ahrens <[email protected]> Closes #10611 Closes #10613
Diffstat (limited to 'module/lua/lstate.c')
-rw-r--r--module/lua/lstate.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/module/lua/lstate.c b/module/lua/lstate.c
index 1b1d948fa..4d196eced 100644
--- a/module/lua/lstate.c
+++ b/module/lua/lstate.c
@@ -214,6 +214,7 @@ static void preinit_state (lua_State *L, global_State *g) {
L->nny = 1;
L->status = LUA_OK;
L->errfunc = 0;
+ L->runerror = 0;
}