lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


One way could be to call lua_error instead of longjmp in your hook, but then you have to remove pcall from the user environment, or he'll be able to catch it.

//Andreas

Gerald Gutierrez skrev:
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 */
    }
}