diff --git a/src/eval.c b/src/eval.c index e2ee41cb5..dd488a984 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1629,6 +1629,7 @@ ldbLog(sdsnew(" next line of code.")); * to start executing a new line. */ void luaLdbLineHook(lua_State *lua, lua_Debug *ar) { scriptRunCtx* rctx = luaGetFromRegistry(lua, REGISTRY_RUN_CTX_NAME); + serverAssert(rctx); /* Only supported inside script invocation */ lua_getstack(lua,0,ar); lua_getinfo(lua,"Sl",ar); ldb.currentline = ar->currentline; diff --git a/src/function_lua.c b/src/function_lua.c index 2e0250ea2..ca89818d8 100644 --- a/src/function_lua.c +++ b/src/function_lua.c @@ -83,6 +83,7 @@ typedef struct registerFunctionArgs { static void luaEngineLoadHook(lua_State *lua, lua_Debug *ar) { UNUSED(ar); loadCtx *load_ctx = luaGetFromRegistry(lua, REGISTRY_LOAD_CTX_NAME); + serverAssert(load_ctx); /* Only supported inside script invocation */ uint64_t duration = elapsedMs(load_ctx->start_time); if (duration > LOAD_TIMEOUT_MS) { lua_sethook(lua, luaEngineLoadHook, LUA_MASKLINE, 0); diff --git a/src/script_lua.c b/src/script_lua.c index 736ddc949..67209615b 100644 --- a/src/script_lua.c +++ b/src/script_lua.c @@ -173,6 +173,7 @@ void* luaGetFromRegistry(lua_State* lua, const char* name) { lua_gettable(lua, LUA_REGISTRYINDEX); if (lua_isnil(lua, -1)) { + lua_pop(lua, 1); /* pops the value */ return NULL; } /* must be light user data */ @@ -838,10 +839,7 @@ static robj **luaArgsToRedisArgv(lua_State *lua, int *argc) { static int luaRedisGenericCommand(lua_State *lua, int raise_error) { int j; scriptRunCtx* rctx = luaGetFromRegistry(lua, REGISTRY_RUN_CTX_NAME); - if (!rctx) { - luaPushError(lua, "redis.call/pcall can only be called inside a script invocation"); - return luaError(lua); - } + serverAssert(rctx); /* Only supported inside script invocation */ sds err = NULL; client* c = rctx->c; sds reply; @@ -1052,10 +1050,7 @@ static int luaRedisSetReplCommand(lua_State *lua) { int flags, argc = lua_gettop(lua); scriptRunCtx* rctx = luaGetFromRegistry(lua, REGISTRY_RUN_CTX_NAME); - if (!rctx) { - luaPushError(lua, "redis.set_repl can only be called inside a script invocation"); - return luaError(lua); - } + serverAssert(rctx); /* Only supported inside script invocation */ if (argc != 1) { luaPushError(lua, "redis.set_repl() requires two arguments."); @@ -1077,10 +1072,7 @@ static int luaRedisSetReplCommand(lua_State *lua) { * Checks ACL permissions for given command for the current user. */ static int luaRedisAclCheckCmdPermissionsCommand(lua_State *lua) { scriptRunCtx* rctx = luaGetFromRegistry(lua, REGISTRY_RUN_CTX_NAME); - if (!rctx) { - luaPushError(lua, "redis.acl_check_cmd can only be called inside a script invocation"); - return luaError(lua); - } + serverAssert(rctx); /* Only supported inside script invocation */ int raise_error = 0; int argc; @@ -1152,10 +1144,7 @@ static int luaLogCommand(lua_State *lua) { /* redis.setresp() */ static int luaSetResp(lua_State *lua) { scriptRunCtx* rctx = luaGetFromRegistry(lua, REGISTRY_RUN_CTX_NAME); - if (!rctx) { - luaPushError(lua, "redis.setresp can only be called inside a script invocation"); - return luaError(lua); - } + serverAssert(rctx); /* Only supported inside script invocation */ int argc = lua_gettop(lua); if (argc != 1) { @@ -1481,11 +1470,6 @@ static void luaCreateArray(lua_State *lua, robj **elev, int elec) { /* The following implementation is the one shipped with Lua itself but with * rand() replaced by redisLrand48(). */ static int redis_math_random (lua_State *L) { - scriptRunCtx* rctx = luaGetFromRegistry(L, REGISTRY_RUN_CTX_NAME); - if (!rctx) { - return luaL_error(L, "math.random can only be called inside a script invocation"); - } - /* the `%' avoids the (rare) case of r==1, and is needed also because on some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */ lua_Number r = (lua_Number)(redisLrand48()%REDIS_LRAND48_MAX) / @@ -1514,10 +1498,6 @@ static int redis_math_random (lua_State *L) { } static int redis_math_randomseed (lua_State *L) { - scriptRunCtx* rctx = luaGetFromRegistry(L, REGISTRY_RUN_CTX_NAME); - if (!rctx) { - return luaL_error(L, "math.randomseed can only be called inside a script invocation"); - } redisSrand48(luaL_checkint(L, 1)); return 0; } @@ -1526,6 +1506,7 @@ static int redis_math_randomseed (lua_State *L) { static void luaMaskCountHook(lua_State *lua, lua_Debug *ar) { UNUSED(ar); scriptRunCtx* rctx = luaGetFromRegistry(lua, REGISTRY_RUN_CTX_NAME); + serverAssert(rctx); /* Only supported inside script invocation */ if (scriptInterrupt(rctx) == SCRIPT_KILL) { serverLog(LL_WARNING,"Lua script killed by user with SCRIPT KILL."); diff --git a/tests/unit/functions.tcl b/tests/unit/functions.tcl index a907badbe..8851e4d79 100644 --- a/tests/unit/functions.tcl +++ b/tests/unit/functions.tcl @@ -644,6 +644,15 @@ start_server {tags {"scripting"}} { set _ $e } {*attempted to access nonexistent global variable 'set_repl'*} + test {LIBRARIES - redis.acl_check_cmd from function load} { + catch { + r function load replace {#!lua name=lib2 + return redis.acl_check_cmd('set','xx',1) + } + } e + set _ $e + } {*attempted to access nonexistent global variable 'acl_check_cmd'*} + test {LIBRARIES - malicious access test} { # the 'library' API is not exposed inside a # function context and the 'redis' API is not