]> git.proxmox.com Git - mirror_zfs.git/commit
Fix lua stack overflow on recursive call to gsub()
authorMatthew Ahrens <matthew.ahrens@delphix.com>
Mon, 27 Jul 2020 23:11:47 +0000 (16:11 -0700)
committerGitHub <noreply@github.com>
Mon, 27 Jul 2020 23:11:47 +0000 (16:11 -0700)
commit3eabed74c0fca5dd9f96d2cca13c4a1a16d5c094
treedac524f95cbf222459729fa6af23b2df2d39ac85
parente64cc4954c7862db6a6b4dc978a091ebc3f870da
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 <gwilson@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Ryan Moeller <ryan@ixsystems.com>
Reviewed-by: Allan Jude <allanjude@freebsd.org>
Reviewed-by: Serapheim Dimitropoulos <serapheim@delphix.com>
Signed-off-by: Matthew Ahrens <mahrens@delphix.com>
Closes #10611
Closes #10613
12 files changed:
module/lua/ldebug.c
module/lua/ldo.c
module/lua/llimits.h
module/lua/lstate.c
module/lua/lstate.h
tests/runfiles/common.run
tests/zfs-tests/include/tunables.cfg
tests/zfs-tests/tests/functional/channel_program/lua_core/Makefile.am
tests/zfs-tests/tests/functional/channel_program/lua_core/tst.memory_limit.ksh
tests/zfs-tests/tests/functional/channel_program/lua_core/tst.stack_gsub.err [new file with mode: 0644]
tests/zfs-tests/tests/functional/channel_program/lua_core/tst.stack_gsub.ksh [new file with mode: 0755]
tests/zfs-tests/tests/functional/channel_program/lua_core/tst.stack_gsub.zcp [new file with mode: 0644]