File: sandbox.lua

package info (click to toggle)
instead 3.5.2%2Bdfsg-0.3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,316 kB
  • sloc: ansic: 28,336; sh: 452; makefile: 236
file content (135 lines) | stat: -rw-r--r-- 4,110 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
-- luacheck: globals STANDALONE
-- luacheck: read globals instead
-- luacheck: globals io os debug load loadstring package
-- luacheck: read globals instead_realpath

local function sandbox()
	if STANDALONE or not instead.gamepath then -- not standalone or not sdl-instead
		return
	end
-- luacheck: no unused args
	local check_path = function(realpath, type, find, gsub, savepath, gamepath, path)
-- luacheck: unused args
		if not path then
			return false
		end
		path = realpath(path)
		if not path then
			return false
		end
		local spath = realpath(savepath)
		if not spath then
			return false
		end
		local s = find(path, spath..'/', 1, true)
		if s ~= 1 then
			spath = realpath(gamepath);
			if spath then
				s = find(path, spath..'/', 1, true)
			end
		end
		if s ~= 1 then
			return false
		end
		return true
	end

	local build_sandbox_open = function(realpath, error, type, find, gsub, savepath, gamepath)
		return stead.hook(io.open, function(f, path, acc, ...)
					  if type(acc) ~= 'string' or not find(acc, "[aw+]") then -- only write access
						  return f(path, acc, ...)
					  end
-- luacheck: no unused args
					  if not check_path(realpath, type, find, gsub, savepath, gamepath, path) then
-- luacheck: unused args
						  error ("Access denied (write): ".. path, 3);
						  return false
					  end
					  return f(path, acc, ...)
		end)
	end

	local build_sandbox_remove = function(realpath, error, type, find, gsub, savepath, gamepath)
		return stead.hook(os.remove, function(f, path, ...)
					  if type(path) ~= 'string' then
						  return f(path, ...)
					  end
					  if not check_path(realpath, type, find, gsub, savepath, gamepath, path) then
						  error ("Access denied (remove): ".. path, 3);
						  return false
					  end
					  return f(path, ...)
		end)
	end

	local build_sandbox_rename = function(realpath, error, type, find, gsub, savepath, gamepath)
		return stead.hook(os.rename, function(f, oldname, newname, ...)
					  if not check_path(realpath, type, find, gsub, savepath, gamepath, oldname) or
					  not check_path(realpath, type, find, gsub, savepath, gamepath, newname) then
						  error ("Access denied (rename): ".. oldname .. ', '.. newname, 3);
						  return false
					  end
					  return f(oldname, newname, ...)
		end)
	end

	local build_sandbox_output = function(realpath, error, type, find, gsub, savepath, gamepath)
		return stead.hook(io.output, function(f, path, ...)
					  if type(path) == 'string' and not check_path(realpath, type, find, gsub, savepath, gamepath, path) then
						  error ("Access denied (output): ".. path, 3);
						  return false
					  end
					  return f(path, ...)
		end)
	end

	local build_sandbox_load = function(eval, error, type, find)
		return stead.hook(eval, function(f, str, ...)
			if type(str) == 'string' and find(str, "\x1b", 1, true) == 1 then
				error ("Loading bytecode is forbidden!", 3)
				return false
			end
			return f(str, ...)
		end)
	end

	io.open = build_sandbox_open(instead_realpath, error, type, string.find, string.gsub,
				     instead.savepath(), instead.gamepath());

	os.remove = build_sandbox_remove(instead_realpath, error, type, string.find, string.gsub,
					 instead.savepath(), instead.gamepath());

	os.rename = build_sandbox_rename(instead_realpath, error, type, string.find, string.gsub,
					 instead.savepath(), instead.gamepath());

	io.output = build_sandbox_output(instead_realpath, error, type, string.find, string.gsub,
					 instead.savepath(), instead.gamepath());

	os.execute = function(s)
		print ("Warning: trying to do os.execute: "..s);
	end

	io.popen = function(s)
		print ("Warning: trying to do io.popen: "..s);
	end

	os.tmpname = function(_)
		print ("Warning: trying to do os.tmpname");
	end

	if not stead.rawget(_G, 'DEBUG') then
		debug = nil
	end
	if _VERSION == "Lua 5.1" then
		loadstring = build_sandbox_load(loadstring, error, type, string.find)
		stead.eval = loadstring
	else
		load = build_sandbox_load(load, error, type, string.find)
		stead.eval = load
	end
	package.cpath = ""
	package.preload = {}
	package = nil
end

sandbox()