]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/engine: support for sandboxing pcalls
authorMarek Vavruša <marek.vavrusa@nic.cz>
Wed, 8 Apr 2015 14:22:30 +0000 (16:22 +0200)
committerMarek Vavruša <marek.vavrusa@nic.cz>
Wed, 8 Apr 2015 14:22:30 +0000 (16:22 +0200)
daemon/daemon.mk
daemon/engine.c
daemon/lua/sandbox.lua [moved from daemon/lua/init.lua with 65% similarity]

index 64510f0dfdab6aa2de041e98e98da49a7d21ef0f..a398873114d66ccc3a6df3b7f2decb22c0f78e76 100644 (file)
@@ -8,7 +8,7 @@ kresolved_SOURCES := \
        daemon/main.c
 
 # Embed resources
-daemon/engine.o: daemon/lua/init.inc daemon/lua/config.inc
+daemon/engine.o: daemon/lua/sandbox.inc daemon/lua/config.inc
 %.inc: %.lua
        @$(call quiet,LUAC,$<) -o $<.out $<
        @$(call quiet,XXD,$<) -i - < $<.out > $@
index ae94b09daf19fa92b0c9ce9a28004daea2616f9e..791936d32783eb26d99f763d57358d7d678aa8e4 100644 (file)
@@ -165,6 +165,16 @@ void engine_deinit(struct engine *engine)
        kr_cache_close(engine->resolver.cache);
 }
 
+/** Execute current chunk in the sandbox */
+static int l_sandboxcall(lua_State *L)
+{
+#if LUA_VERSION_NUM >= 502
+       lua_getglobal(L, "_SANDBOX");
+       lua_setupvalue(L, -2, 1);
+#endif
+       return lua_pcall(L, 0, LUA_MULTRET, 0);
+}
+
 int engine_cmd(struct engine *engine, const char *str)
 {
        if (engine == NULL || engine->L == NULL) {
@@ -172,7 +182,10 @@ int engine_cmd(struct engine *engine, const char *str)
        }
 
        /* Evaluate results */
-       int ret = luaL_dostring(engine->L, str);
+       int ret = luaL_loadstring(engine->L, str);
+       if (ret == 0) {
+               ret = l_sandboxcall(engine->L);
+       }
 
        /* Print results. */
        int nres = lua_gettop(engine->L);
@@ -195,13 +208,17 @@ int engine_cmd(struct engine *engine, const char *str)
 /* Execute byte code */
 #define l_dobytecode(L, arr, len, name) \
        (luaL_loadbuffer((L), (arr), (len), (name)) || lua_pcall((L), 0, LUA_MULTRET, 0))
+/** Load file in a sandbox environment. */
+#define l_dosandboxfile(L, filename) \
+       (luaL_loadfile((L), (filename)) || l_sandboxcall((L)))
+
 static int engine_loadconf(struct engine *engine)
 {
        /* Init environment */
-       static const char l_init[] = {
-               #include "daemon/lua/init.inc"
+       static const char sandbox_bytecode[] = {
+               #include "daemon/lua/sandbox.inc"
        };
-       if (luaL_dostring(engine->L, l_init) != 0) {
+       if (l_dobytecode(engine->L, sandbox_bytecode, sizeof(sandbox_bytecode), "init") != 0) {
                fprintf(stderr, "[system] error %s\n", lua_tostring(engine->L, -1));
                lua_pop(engine->L, 1);
                return kr_error(ENOEXEC);
@@ -210,13 +227,13 @@ static int engine_loadconf(struct engine *engine)
        /* Load config file */
        int ret = 0;
        if(access("config", F_OK ) != -1 ) {
-               ret = luaL_dofile(engine->L, "config");
+               ret = l_dosandboxfile(engine->L, "config");
        } else {
                /* Load defaults */
-               static const char config_init[] = {
+               static const char config_bytecode[] = {
                        #include "daemon/lua/config.inc"
                };
-               ret = luaL_dostring(engine->L, config_init);
+               ret = l_dobytecode(engine->L, config_bytecode, sizeof(config_bytecode), "config");
        }
 
        /* Evaluate */
similarity index 65%
rename from daemon/lua/init.lua
rename to daemon/lua/sandbox.lua
index 8792674366b7a6424c49a8c5a64fe2e4ac80645e..6249f489a94fd457d2aa6c3fa2bffec5d2ae265e 100644 (file)
@@ -12,9 +12,9 @@ setmetatable(modules, {
        end
 })
 
--- Some services are append-only
-function protect(defined)
-       local __protected = { ['modules'] = true }
+-- Make sandboxed environment
+function make_sandbox(defined)
+       local __protected = { modules = true, cache = true, net = true }
        return setmetatable({}, {
                __index = defined,
                __newindex = function (t, k, v)
@@ -28,5 +28,10 @@ function protect(defined)
                end
        })
 end
--- _G = protect(getfenv(0))
--- setfenv(0, _G)
+
+if setfenv then -- Lua 5.1 and less
+       _G = make_sandbox(getfenv(0))
+       setfenv(0, _G)
+else -- Lua 5.2+
+       _SANDBOX = make_sandbox(_ENV)
+end