Hello all,
I'm trying to avoid a potential denial of service situation with the
execution of Lua code where a user can enter code that takes a long time
to run, thereby hanging the interpreter. Proving to be more difficult
than it seems.
My solution registers a hook function that executes based on the count
hook. It checks the current time and if execution has timed out, it does
a longjmp out of the interpreter and back into the host application.
Something like the code below. It works fine, with the exception that
this only ever works once on a given lua_State because if the call ever
times out, the lua_State will no longer call hooks on subsequent
execution (because L->activehook is set to 0 and never gets set back to
1 because my longjmp bypasses that code). Lua hides the activehook
variable from the host so I can't reset it.
Are there any good solutions to this, or alternatives to implementing
the same functionality?
Thanks,
Gerald.
static void my_hook(lua_State *L, lua_Debug *ar) {
/* ... get lctx containing timeout values */
if (time(NULL) >= lctx->timeout) {
longjmp(lctx->timeout_jmp, 1);
}
}
static void timed_lua(lua_State *L) {
/* ... Set up lctx containing jmp_buf for longjmp and timeout values */
lua_sethook(L, my_hook, LUA_MASKCOUNT, 1024);
if (setjmp(lctx->timeout_jmp) == 0) {
lctx->timeout = time(NULL) + timeout;
rv = luaL_dostring(L, "...");
/* Didn't time out */
} else {
/* Timed out */
}
}