Page 1 of 1

[Solved] Can I use dofile instead of require somehow?

PostPosted: Mon Jun 03, 2019 17:11
by texmex
Because of the MT Lua security model I can’t use require if I don’t mark the mod as a ”trusted mod”. Now, luarocks has a lot of useful libraries but enabling them for a mod requires the use of require, so to speak. I still want the mod securely sandboxed. Is there a way to use dofile instead somehow? I don’t care if it’s ugly.

It’s weird to me that the modding API is designed in a way that can’t leverage the power of external generic Lua libraries by default.

Re: Can I use dofile instead of require somehow?

PostPosted: Mon Jun 03, 2019 18:29
by Krock
If there was a way, the mod security would be kinda pointless because any mod could just run code from any C library. Note that C code cannot be protected by Minetest, thus `require` has to be guarded in any case.
There's no sane workaround for this. I think there are still ways to leak the insecure environment, but that's surely not your goal.

Re: Can I use dofile instead of require somehow?

PostPosted: Mon Jun 03, 2019 18:49
by texmex
Thank you for clarifying.

So allowing require allows for code execution not only of other Lua libs but C (and others?) as well?

Re: Can I use dofile instead of require somehow?

PostPosted: Mon Jun 03, 2019 19:30
by Krock
texmex wrote:So allowing require allows for code execution not only of other Lua libs but C (and others?) as well?


As soon the function `int luaopen_MYLIBRARY(lua_State *L)` is exported to the dynamic library/Lua, it's possible to load it from Lua using `require` and call functions which were added inside that constructor-like function.

Re: Can I use dofile instead of require somehow?

PostPosted: Mon Jun 03, 2019 20:09
by texmex
Right. Again, thanks for clarifying. :)

Re: Can I use dofile instead of require somehow?

PostPosted: Mon Jun 03, 2019 20:11
by rubenwardy
Require does not load any C code or Lua by itself.

1. Require first checks if the module has already been loaded, and if so returns it from the cache.
2. Require then attempts to find the module in the package path
3. Require calls dofile on the module

so, in code:

Code: Select all
function require(name)
    -- Don't load twice
    if registry.__loaded[name] then
        return registry.__loaded[name]
    end

    -- find main lua file for given module
    local path = find(name)

    -- dofile
    local ret = dofile(path)
    registry.__loaded[name] = ret
    return ret
end


The reason that require is currently disabled is because it is hardcoded to use Lua's dofile rather than our own safe dofile.

Here is a PR which adds our own safe require: https://github.com/minetest/minetest/pull/7621

Re: [Solved, no] Can I use dofile instead of require somehow

PostPosted: Mon Jun 03, 2019 20:14
by texmex
In my case I wanted to use a csv library and so I tried to include it with dofile. If the functions inside where global instead of local it seemed that it could’ve worked. I assumed require would deal with this namespace thing but I’ve no idea how it works.

Re: [Solved, no] Can I use dofile instead of require somehow

PostPosted: Mon Jun 03, 2019 20:17
by rubenwardy
texmex wrote:In my case I wanted to use a csv library and so I tried to include it with dofile. If the functions inside where global instead of local it seemed that it could’ve worked. I assumed require would deal with this namespace thing but I’ve no idea how it works.


You can return things through dofile too. If the library is in pure Lua, you can just include it in your mod and replace any require calls with dofile calls with exact paths

Re: [Solved, no] Can I use dofile instead of require somehow

PostPosted: Mon Jun 03, 2019 20:21
by texmex
Oh okay. Maybe I just didn’t know what I was doing. Kudos for making that PR, I hope it will be merged some day. Like, I know modders usually want to write selfcontained mods without dependencies but at some point reinventing wheels instead of building actual games gets tiresome.