Centralize Lua sandboxing
authorRobin Gareus <robin@gareus.org>
Wed, 9 Aug 2017 02:07:23 +0000 (04:07 +0200)
committerRobin Gareus <robin@gareus.org>
Thu, 10 Aug 2017 00:25:49 +0000 (02:25 +0200)
libs/ardour/luaproc.cc
libs/ardour/luascripting.cc
libs/ardour/session.cc
libs/lua/lua/luastate.h
libs/lua/luastate.cc

index 0e181dbb6b80734ee5f88f541bc3963ed41d578d..6581743771daf0cc38597068c7433ee0bc9abd46 100644 (file)
@@ -163,7 +163,7 @@ LuaProc::init ()
        lua_setglobal (L, "self");
 
        // sandbox
-       lua.do_command ("io = nil os = nil loadfile = nil require = nil dofile = nil package = nil debug = nil");
+       lua.sandbox (true);
 #if 0
        lua.do_command ("for n in pairs(_G) do print(n) end print ('----')"); // print global env
 #endif
index 8e9157afe8e00c8c0029f0b4e96c821e44ff73c0..0367f5830d323e894d4e4fbd9aad9d4b3b00fe7c 100644 (file)
@@ -179,8 +179,7 @@ LuaScripting::scan_script (const std::string &fn, const std::string &sc)
 
        lua_State* L = lua.getState();
        lua.Print.connect (&LuaScripting::lua_print);
-
-       lua.do_command ("io = nil;");
+       lua.sandbox (true);
 
        lua.do_command (
                        "ardourluainfo = {}"
@@ -339,7 +338,7 @@ LuaScriptParams::script_params (const std::string& s, const std::string &pname,
 
        LuaState lua;
        lua_State* L = lua.getState();
-       lua.do_command ("io = nil;");
+       lua.sandbox (true);
        lua.do_command ("function ardour () end");
 
        try {
@@ -416,6 +415,7 @@ LuaScripting::try_compile (const std::string& script, const LuaScriptParamList&
        }
        LuaState l;
        l.Print.connect (&LuaScripting::lua_print);
+       l.sandbox (true);
        lua_State* L = l.getState();
 
        l.do_command (""
@@ -425,7 +425,7 @@ LuaScripting::try_compile (const std::string& script, const LuaScriptParamList&
                        "  assert(type(f) == 'string', 'Assigned ByteCode must be string')"
                        "  local factory = load(f)"
                        "  assert(type(factory) == 'function', 'Factory is a not a function')"
-                       "  local env = _ENV;  env.f = nil env.debug = nil os.exit = nil"
+                       "  local env = _ENV; env.f = nil env.os = nil env.io = nil"
                        "  load (string.dump(factory, true), nil, nil, env)(a)"
                        " end"
                        );
@@ -454,6 +454,7 @@ LuaScripting::get_factory_bytecode (const std::string& script, const std::string
 {
        LuaState l;
        l.Print.connect (&LuaScripting::lua_print);
+       l.sandbox (true);
        lua_State* L = l.getState();
 
        l.do_command (
index 91f67cf3da64738b379c4697dee8a87a699d0d72..764e05c3e888df858a3d57abb3a1a493038c6ab2 100644 (file)
@@ -5500,6 +5500,7 @@ Session::setup_lua ()
        lua.Print.connect (&_lua_print);
 #endif
        lua.tweak_rt_gc ();
+       lua.sandbox (true);
        lua.do_command (
                        "function ArdourSession ()"
                        "  local self = { scripts = {}, instances = {} }"
@@ -5516,7 +5517,6 @@ Session::setup_lua ()
                        "   assert(type(a) == 'table' or type(a) == 'nil', 'Given argument is invalid')"
                        "   assert(self.scripts[n] == nil, 'Callback \"'.. n ..'\" already exists.')"
                        "   self.scripts[n] = { ['f'] = f, ['a'] = a }"
-                       "   local env = _ENV;  env.f = nil env.io = nil env.os = nil env.loadfile = nil env.require = nil env.dofile = nil env.package = nil env.debug = nil"
                        "   local env = { print = print, tostring = tostring, assert = assert, ipairs = ipairs, error = error, select = select, string = string, type = type, tonumber = tonumber, collectgarbage = collectgarbage, pairs = pairs, math = math, table = table, pcall = pcall, bit32=bit32, Session = Session, PBD = PBD, Timecode = Timecode, Evoral = Evoral, C = C, ARDOUR = ARDOUR }"
                        "   self.instances[n] = load (string.dump(f, true), nil, nil, env)(a)"
                        "   Session:scripts_changed()" // call back
index 5a5c939c2ad59a7011268bc06c13fd24dea33fdd..cdc7f2b2bfeae818daf6862762f7a48a8bff08e3 100644 (file)
@@ -36,6 +36,7 @@ public:
        void collect_garbage ();
        void collect_garbage_step ();
        void tweak_rt_gc ();
+       void sandbox (bool rt_safe = false);
 
        sigc::signal<void,std::string> Print;
 
index 8b704fbe6a58ce6c374958bfdd6a8bdced667ea7..80ce41944c539c9b07728ed4c26645209d4354fa 100644 (file)
@@ -88,6 +88,15 @@ LuaState::tweak_rt_gc () {
        lua_gc (L, LUA_GCSETSTEPMUL, 100);
 }
 
+void
+LuaState::sandbox (bool rt_safe) {
+       do_command ("loadfile = nil dofile = nil require = nil dofile = nil package = nil debug = nil os.exit = nil os.setlocale = nil rawget = nil rawset = nil coroutine = nil module = nil");
+       if (rt_safe) {
+               do_command ("os = nil io = nil");
+       }
+}
+
+
 void
 LuaState::print (std::string text) {
        Print (text); /* EMIT SIGNAL */