Menu

#42 You can use the string metatable to kill anything that uses LuaJ

v3.0-beta1
wont-fix
nobody
9
2015-03-16
2014-12-02
SoniEx 2
No

x=getmetatable''; while true do table.insert(x, {}) end

I'm pretty sure that won't ever get collected/tossed away...

Isn't this supposed to be a reimplementation of the Lua interpreter in Java? Where are the Lua states?! How am I supposed to sandbox the string metatable?!

Discussion

  • James Roseborough

    If you plan to run a server with potentially hostile codes, you should limit access to shared metatables using the __metatable tag, for example:

        // Create a script that writes to the string metatable
        String script =  "return rawset(getmetatable('abc'), 'foo', 'bar')";                 
        Globals globals = JsePlatform.debugGlobals();
        LuaValue chunk = globals.load(script, "test");
    
        // Initially, the write succeeds
        System.out.println(chunk.call().toString());
    
        // Make the string metatable inaccessible to lua scripts
        LuaString.s_metatable.set(LuaValue.METATABLE, LuaValue.FALSE); 
    
        // Try again, it will fail
        System.out.println(chunk.call().toString());
    

    The first call will succeed, the second will fail.

    You should do the same for the LuaNumber and LuaBoolean metatables.

    And of course do not use the debug library because it can then get at the underlying metatables via the debug library's 'getmetatable' function which ignores metatags.

    If you are careful enough you can also provide read-only access to these metatable, but that it more difficult since it's possible to rewrite an existing value without causing __newindex to be invoked, so the exposed metatable should be a read-only shadow that falls back to the actual metatable.

    This limitation of luaj is known and was designed this way as a tradeoff to prevent the overhead of all lua strings and numbers from containing a pointer to an environment, and passing those environments around as strings are created and destroyed.

    As for where are the lua states, this is a rewrite of lua features in a more Java-centric way than the C-based lua code base. For example you can compile your scripts to Java and not have a lua VM stack at all (so-called stackless execution). So there is not a 1-1 correspondence between the C-based implementation and the luaj implementation.

     
  • James Roseborough

    • status: open --> wont-fix
     
  • SoniEx 2

    SoniEx 2 - 2015-03-16

    What if I want/need per-environment string/number/etc metatable? Is there no way to get that with LuaJ? Should I just use JNI then?

     

Log in to post a comment.