local function stringtotable(sdata, safe)
if sdata:byte(1) == 27 then return nil, "binary bytecode prohibited" end
local f, message = assert(loadstring(sdata))
if not f then return nil, message end
if safe then
setfenv(f, safe_env)
else
setfenv(f, env)
end
return f()
end
function core.deserialize(sdata, safe)
local table = {}
local okay, results = pcall(stringtotable, sdata, safe)
if okay then
return results
end
core.log('error', 'core.deserialize(): '.. results)
return nil
end
http://lua-users.org/wiki/SandBoxes wrote:You should start by trusting nothing and only permit things that you are absolutely sure are safe (i.e. whitelist rather than blacklist approach).
local ret = {coroutine.resume(co)}
-- dronetest.log("Computer "..id.." result:"..dump(ret))
09:53:07: ACTION[ServerThread]: dronetest: STATUS: suspended
09:53:07: ACTION[ServerThread]: dronetest: TYPE: table
09:53:07: ACTION[ServerThread]: dronetest: System #3 has been activated, now 1 systems active.
09:53:07: ACTION[ServerThread]: dronetest: system 3 generated output: System #3 has been activated.
09:53:07: ACTION[ServerThread]: dronetest: STATUS: suspended
09:53:07: ACTION[ServerThread]: dronetest: TYPE: table
09:53:07: ACTION[ServerThread]: dronetest: System #2 has been activated, now 2 systems active.
09:53:07: ACTION[ServerThread]: dronetest: system 2 generated output: System #2 has been activated.
09:53:07: ACTION[ServerThread]: dronetest: System #2's main process has ended! Restarting soon...
09:53:07: ACTION[ServerThread]: dronetest: System #3's main process has ended! Restarting soon...
16:56:04: ACTION[ServerThread]: dronetest: on_receive_fields received ''
16:56:04: ACTION[ServerThread]: dronetest: STATUS: suspended
16:56:04: ACTION[ServerThread]: dronetest: TYPE: table
16:56:04: ACTION[ServerThread]: dronetest: System #1 has been activated, now 1 systems active.
16:56:04: ACTION[ServerThread]: dronetest: system 1 generated output: System #1 has been activated.
16:56:04: ACTION[ServerThread]: dronetest: system 1 generated output: System #1 is booting!
16:56:04: ACTION[ServerThread]: dronetest: system 1 generated output: Finished booting #1, dropping to shell.
SEND
17:08:17: ACTION[ServerThread]: dronetest: system 1 generated output: System #1 is booting!
17:08:17: ACTION[ServerThread]: dronetest: system 1 generated output: bootstrap env: pairs (function)
17:08:17: ACTION[ServerThread]: dronetest: system 1 generated output: bootstrap env: table (table)
17:08:17: ACTION[ServerThread]: dronetest: system 1 generated output: bootstrap env: mod_dir (string)
17:08:17: ACTION[ServerThread]: dronetest: system 1 generated output: bootstrap env: fs (table)
17:08:17: ACTION[ServerThread]: dronetest: system 1 generated output: bootstrap env: sys (table)
17:08:17: ACTION[ServerThread]: dronetest: system 1 generated output: bootstrap env: peripheral (table)
17:08:17: ACTION[ServerThread]: dronetest: system 1 generated output: bootstrap env: processInput (function)
17:08:17: ACTION[ServerThread]: dronetest: system 1 generated output: bootstrap env: dump (function)
17:08:17: ACTION[ServerThread]: dronetest: system 1 generated output: bootstrap env: ipairs (function)
17:08:17: ACTION[ServerThread]: dronetest: system 1 generated output: bootstrap env: mod_name (string)
17:08:17: ACTION[ServerThread]: dronetest: system 1 generated output: bootstrap env: term (table)
17:08:17: ACTION[ServerThread]: dronetest: system 1 generated output: bootstrap env: print (function)
17:08:17: ACTION[ServerThread]: dronetest: system 1 generated output: bootstrap env: math (table)
17:08:17: ACTION[ServerThread]: dronetest: system 1 generated output: bootstrap env: getId (function)
17:08:17: ACTION[ServerThread]: dronetest: system 1 generated output: bootstrap env: os (table)
17:08:17: ACTION[ServerThread]: dronetest: system 1 generated output: bootstrap env: _G (table)
17:08:17: ACTION[ServerThread]: dronetest: system 1 generated output: bootstrap env: pcall (function)
17:08:17: ACTION[ServerThread]: dronetest: system 1 generated output: bootstrap env: string (table)
17:08:17: ACTION[ServerThread]: dronetest: system 1 generated output: bootstrap env: type (function)
17:08:17: ACTION[ServerThread]: dronetest: system 1 generated output: bootstrap env: count (function)
17:08:17: ACTION[ServerThread]: dronetest: system 1 generated output: bootstrap env: shell (table)
17:08:17: ACTION[ServerThread]: dronetest: system 1 generated output: bootstrap env: xpcall (function)
17:08:17: ACTION[ServerThread]: dronetest: system 1 generated output: Finished booting #1, dropping to shell.
ninnghazad wrote:the resume-line in init.lua is what keeps computers running.
that resume executes the systems' coroutines until they yield again (or quit).
each computer has it's own coroutine.
<rest of your post>
function wrapfunc(func, env)
return setfenv(function(...) return func(...) end, env)
end
print("Booting...")
coroutine.yield()
coroutine.yield()
...
-- Load bootstrap code once
local bootstrap = readFile(mod_dir.."/bootstrap.lua")
dronetest.log("bootstrap:"..dump(bootstrap))
...
dronetest: readFile: "/home/<username>/src/minetest/bin/../mods/dronetest/dronetest/bootstrap.lua" is not a valid filename.
That way, computers can't run getfenv(sys.receiveDigilineMessage).minetest and get the global minetest table.
I already mostly did this and will push it soon.
print("HEHO!")
return true
I'm now fixing readFile to allow .. but still enforce sandboxing.
Are you using "userspace" to refer to sandboxed or normal code? You mean sandboxed code (code the end user writes), right?
The sandbox function I wrote but haven't committed yet goes through a table you pass it and does this to all of the functions inside.
This won't happen today, but I plan to make a function that creates a userspace environment for each system, instead of copying one table. This will make system-specific closures possible and not a headache. It will also fix the the sys.id bug.
ninnghazad wrote:yes, i refer to the environment and coroutine the player writes and executes code in as userspace.
that sounds proper. however, we must make sure that whatever that function returns does not contain a loophole via a returned function or object. so we need to inspect lua apis we want in userspace for unsafe return values, and wrap these in apis (where we do something with the return-value and return a userspace-version or interpretation of it)
- the other we add to the table-o-userspace-functions and walk through with your function.
coroutine for example needed an api - math.* or string.* may not need one, as they return rather predictable stuff.
Ye to that - that is how it is supposed to be, but right now it's more a mess of copies and links. system-specific stuff at that point may be usefull later on, to have different access-permissions per player/system or fractions of systems and so on.
EDIT: in case you didn't notice in the readme-change, theres a texture-bug somewhere, so updating displays leaks a bit of mem everytime - switch displays to empty channel to stop updating if that becomes a problem.
I think we should separate the computer innards from init.lua into their own file, for manageability.
which timezone do you live in
we can either have the wrapper sandbox things itself (slower but foolproof) or expect API functions to do it themselves (faster but more dangerous).
Whoever does this should also split it into two files at the same time.
Do digilines LCDs have this problem too? Does breaking and re-placing a display free the lost memory?
ninnghazad wrote:Ye, that init.lua has grown quickly. Lets split it up.
apis in that regard not only have the purpose of safely getting data to userspace, but also to provide it in a form the player may use, or combine several global-calls to form some userspace-information. if it is just about a function to be used more or less directly, theres no need. but if it is about producing complex output, a specific wrapper is needed, what i consider apis for. also we have to remember that being able not load parts of the userspace may be good when number of functions grows, to reduce server-time needed to boot systems. but i would consider those apis that exist in normal lua also to be part of a fixed minimal set.
Well, you said you had stuff uncommited, so you do it i'd say right after commiting (even if not completely done). As it's weekend however that would have to happen today, so i can code myself silly over the weekend. well if i feel like it. i can split tonight too if you can't find the time.
thought of leaving init.lua with actual init and includes, and then have computer/drone/util and probably more as we go on.
Probably yes, but due to their tiny texture, it will not be nearly as noticable. And nope, not even exiting to menu does. Only quitting game. I assume this will piss of other people too, so it will sooner than later be fixed.
Maybe we could put a metatable.__index on _G to automatically load apis when they're first needed?
If you decide to split init.lua, please tell me as soon as you decide to, so I don't also do it and make a mess.
This leak is only on the client, right? Restarting the client will fix it?
Users browsing this forum: No registered users and 11 guests