Skip to content

Commit af5a214

Browse files
author
JLague
committed
add execution of modulefiles from a modulefile
Some modulefiles may execute another modulefile, which may modify the PATH variable. This is generally done with the dofile() or loadfile() function, but they break out of the sandbox. By redefining these functions so the file is executed in the sandbox env, modulefiles can be safely loaded from within another modulefile.
1 parent 9767c52 commit af5a214

File tree

1 file changed

+52
-28
lines changed

1 file changed

+52
-28
lines changed

src/lua/sandbox.lua

Lines changed: 52 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,22 @@ function getenv (...)
5050
if val then return val else return "" end
5151
end
5252

53+
-- The bare minimum to check for PATH modifications in modulefiles
54+
test_env = {
55+
pathJoin = pathJoin,
56+
prepend_path = handle_path,
57+
append_path = handle_path,
58+
os = {getenv = getenv},
59+
assert = assert,
60+
error = error,
61+
ipairs = ipairs,
62+
pairs = pairs,
63+
}
64+
5365
meta_table.__index = fake_func
5466

67+
-- These functions may get called if the modulefile tries to use a
68+
-- function which isn't defined in the test env
5569
local meta_obj = {
5670
__index = fake_func,
5771
__call = fake_func,
@@ -62,49 +76,59 @@ local meta_obj = {
6276
__le = fake_compare,
6377
}
6478

65-
test_env = {
66-
pathJoin = pathJoin,
67-
prepend_path = handle_path,
68-
append_path = handle_path,
69-
os = {getenv = getenv},
70-
assert = assert,
71-
error = error,
72-
}
73-
7479
setmetatable(fake_obj, meta_obj)
7580
setmetatable(test_env, meta_table)
7681

7782
--------------------------------------------------------------------------
78-
-- This function is what actually "loads" a modulefile with protection
79-
-- against modulefiles call functions they shouldn't or syntax errors
80-
-- of any kind.
83+
-- Load the provided code in a sandbox environment and return it as a
84+
-- function. This function works with Lua 5.1.
8185
-- @param untrusted_code A string containing lua code
82-
83-
local function run5_1(untrusted_code)
84-
paths = {}
86+
local function loadcode5_1(untrusted_code)
8587
if untrusted_code:byte(1) == 27 then error("binary bytecode prohibited") end
8688
local untrusted_function, message = loadstring(untrusted_code)
8789
if not untrusted_function then error(message) end
8890
setfenv(untrusted_function, test_env)
89-
untrusted_function()
90-
return paths
91+
return untrusted_function
9192
end
9293

9394
--------------------------------------------------------------------------
94-
-- This function is what actually "loads" a modulefile with protection
95-
-- against modulefiles call functions they shouldn't or syntax errors
96-
-- of any kind. This run codes under environment [Lua 5.2] or later.
95+
-- Load the provided code in a sandbox environment and return it as a
96+
-- function. This function works with Lua 5.2 or higher.
9797
-- @param untrusted_code A string containing lua code
98-
local function run5_2(untrusted_code)
99-
paths = {}
98+
local function loadcode5_2(untrusted_code)
10099
local untrusted_function, message = load(untrusted_code, nil, 't', test_env)
101100
if not untrusted_function then error(message) end
102-
untrusted_function()
103-
return paths
101+
return untrusted_function
104102
end
105103

104+
loadcode = (_VERSION == "Lua 5.1") and loadcode5_1 or loadcode5_2
105+
106106
--------------------------------------------------------------------------
107-
-- Define two version: Lua 5.1 or 5.2. It is likely that
108-
-- The 5.2 version will be good for many new versions of
109-
-- Lua but time will only tell.
110-
sandbox_run = (_VERSION == "Lua 5.1") and run5_1 or run5_2
107+
-- Read an entire file and load it's code as a function in a sandbox env.
108+
-- @param filename The name/path of the file to load
109+
function loadfile(filename)
110+
local file = assert(io.open(filename, "r"))
111+
local code = file:read("*a")
112+
file:close()
113+
return loadcode(code)
114+
end
115+
116+
--------------------------------------------------------------------------
117+
-- Execute a lua file in a sandbox environment.
118+
-- @param filename The name/path of the file to load
119+
function dofile(filename)
120+
return assert(loadfile(filename))()
121+
end
122+
123+
-- add the functions to the sandbox env
124+
test_env.loadfile = loadfile
125+
test_env.dofile = dofile
126+
127+
--------------------------------------------------------------------------
128+
-- Load the provided code in a sandbox environment and execute it
129+
-- @param untrusted_code A string containing lua code
130+
function sandbox_run(untrusted_code)
131+
paths = {}
132+
loadcode(untrusted_code)()
133+
return paths
134+
end

0 commit comments

Comments
 (0)