How to execute an untrusted Lua file in its own environment from the C API

前端 未结 3 829
花落未央
花落未央 2021-02-06 10:48

I want to execute an untrusted .lua file in its own environment by calling lua_setfenv() so that it cannot affect any of my code.

The documentation for that function tho

3条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2021-02-06 11:40

    By the way, this is what I ended up doing:

    /* Loads, compiles and executes an unstrusted file. */
    bool Lua::RunUntrustedFile(const string& path)
    {
        if(luaL_loadfile(mState, path.c_str()))
        {
            ErrorLog(lua_tostring(mState, 1));
            Pop(1);
            return false;
        }
    
        Lua::SetMaximumInstructions(100000000);
        lua_newtable(mState);
        lua_setglobal(mState, "upload");
        ASSERT(Lua::GetStackSize() == 1);
        lua_getglobal(mState, "upload");
        ASSERT_ALWAYS(lua_setfenv(mState, 1) != 0);
        ASSERT(Lua::GetStackSize() == 1);
    
        if(lua_pcall(mState, 0, 0, 0))
        {
            Lua::ClearMaximumInstructions();
            ErrorLog(lua_tostring(mState, -1));
            Pop(1);
            return false;
        }
    
        ASSERT(Lua::GetStackSize() == 0);
        Lua::ClearMaximumInstructions();
    
        return true;
    }
    

    "Support" functions:

    static void Pop(int elements = 1) { lua_pop(mState, elements); }
    
    /* Sets a maximum number of instructions before throwing an error */
    static void SetMaximumInstructions(int count) {
        lua_sethook(mState, &Lua::MaximumInstructionsReached, LUA_MASKCOUNT, count);
    }
    static void ClearMaximumInstructions() {
        lua_sethook(mState, &Lua::MaximumInstructionsReached, 0, 0);
    }
    
    static void MaximumInstructionsReached(lua_State *, lua_Debug *)
    {
        Error("The maximum number of instructions has been reached");
    }
    
    static int GetStackSize() { return lua_gettop(mState); }
    

提交回复
热议问题