diff options
author | Daniel Silverstone <dsilvers@digital-scurf.org> | 2015-11-02 14:00:11 +0000 |
---|---|---|
committer | Daniel Silverstone <dsilvers@digital-scurf.org> | 2015-11-02 14:00:11 +0000 |
commit | 356238f901e84171ceb8361ceb63e0c3444b31f7 (patch) | |
tree | 64d19533d92c90cf9d77bf4a543ccc1035cb14a3 /lib | |
parent | 968ec2e65eb4b1abcc4203c32d856c8097a87d1c (diff) | |
download | supple-356238f901e84171ceb8361ceb63e0c3444b31f7.tar.gz |
Add user documentation. Skipping internal docs for now
Diffstat (limited to 'lib')
-rw-r--r-- | lib/supple.lua | 10 | ||||
-rw-r--r-- | lib/supple/host.lua | 84 | ||||
-rw-r--r-- | lib/supple/sandbox.lua | 19 | ||||
-rw-r--r-- | lib/supple/track.lua | 35 |
4 files changed, 146 insertions, 2 deletions
diff --git a/lib/supple.lua b/lib/supple.lua index 513d3ac..f24df24 100644 --- a/lib/supple.lua +++ b/lib/supple.lua @@ -7,6 +7,16 @@ -- For licence terms, see COPYING -- +--- Sandbox, for Untrusted Procedure Partitioning in Lua, Engine. +-- +-- Supple is a mechanism for partitioning untrusted Lua code into a separate +-- process wherein it is run sandboxed from the environment in an attempt to +-- reduce the attack surface to a level at which administrators will be +-- prepared to run arbitrary code from untrusted (or even expected-malicious) +-- third parties. +-- +-- * To see how to use supple, start at `supple.host.run`. + local capi = require 'supple.capi' local request = require 'supple.request' local objects = require 'supple.objects' diff --git a/lib/supple/host.lua b/lib/supple/host.lua index d782115..9f0e016 100644 --- a/lib/supple/host.lua +++ b/lib/supple/host.lua @@ -9,6 +9,17 @@ -- For licence terms, see COPYING -- +--- Running the host-side of sandboxed code +-- +-- When running code in Supple sandboxes, the starting point is this module. +-- The host application should require supple and then begin from here... +-- +-- local supple = require 'supple' +-- print(supple.sandbox.run("return ...", "example code", "arg1", "arg2")) +-- -- Expect: 'arg1 arg2' as output +-- + + local luxio = require 'luxio' local subprocess = require 'luxio.subprocess' @@ -71,6 +82,21 @@ local function run_wrapper() return proc, fds[2] end +--- Run some code in a Supple sandbox +-- +-- Call this routine to run some code in a Supple sandbox. The code is +-- compiled and run entirely within the sandbox process. Any kind of value +-- can be passed to the code as an argument. Intrinsics are transferred +-- immediately (numbers, booleans, nils, strings) but complex values (tables, +-- userdata, and functions) are sent over as a proxy and actions on those +-- values are proxied back to the host to be run. Users of Supple should be +-- aware that those routines are therefore not sandboxed. +-- +-- @tparam string codestr The code to run in the sandbox, as a string. +-- @tparam string codename The name to give to the code running in the sandbox. +-- @param[opt] ... Arguments to pass to the code running in the sandbox. +-- @function run + local function run_sandbox(codestr, codename, ...) -- Prepare and start a sandbox, -- compiling the codestr and running it @@ -78,7 +104,7 @@ local function run_sandbox(codestr, codename, ...) local child, commsfd = run_wrapper() counter = counter + 1 - objects.set_name(("host[%d,%%d]"):format(counter)) + objects.set_name(("%s[%d,%%d]"):format(hostname,counter)) comms._set_fd(commsfd) objects.set_proc_call(comms.call) @@ -132,19 +158,75 @@ local function run_sandbox(codestr, codename, ...) end end +--- +-- Load a string into the sandbox and return it as a wrappered function. +-- +-- This loads the given string (with given name) into the sandbox interpreter +-- and then wrappers the function and returns it to the caller. This can then +-- be used to call code inside the sandbox. This is the entry point to load +-- further code into the sandbox and should only be called during running +-- sandboxed code (i.e. `supple.host.run` is running) +-- +-- @tparam string codestr The code to be loaded in the sandboxed interpreter +-- @tparam string codename The name to be given to the code when it is loaded +-- @treturn function The wrappered function which can then be called or handed +-- back to the sandbox as needed. +-- @treturn table The function environment for the loaded sandboxed code. +-- @function loadstring + local function sandboxed_loadstring(codestr, codename) return comms.call("supple:loadstring", "__call", codestr, codename) end +--- +-- Set the name by which the host refers to itself in traces. +-- +-- Calling this resets the host sandbox counter and sets the name of the host +-- to the given new name. This mostly has an effect on object names and trace +-- data which typically only appear if the user of Supple chooses to trace the +-- activity of the sandbox, or if an error occurs. +-- +-- @tparam string newname The new host name to set +-- @function set_name + local function set_hostname(newname) hostname = newname counter = 0 end +--- +-- Set a new limits table for use in a new sandbox instance. +-- +-- When a sandbox is run (from `supple.host.run`) it has a number of soft +-- limits sent to it to be honoured during the runtime of the sandbox. +-- Normally the sandbox limits itself only by hard limits, but this call allows +-- tighter soft limits to be set if so-desired. +-- +-- The table provided takes the form: +-- +-- { [count = maxopcodestorun], [memory = maxbytestouse] } +-- +-- If you call this function then at least one, but optionally both of the +-- count and memory table entries need to be present. +-- +-- @tparam table newlimits The new soft-limits for any new sandboxes +-- @function set_limits + local function set_limits(newlimits) limits = newlimits end +--- +-- Set a new globals table to be used by new sandbox runs. +-- +-- When a sandboxed function is run, it is run within a given globals table. +-- The globals in question are provided by calling this function. Remember +-- that the table will be passed *shallowly* and new globals created by the +-- sandboxed code will not be copied back to the host. +-- +-- @tparam table newglobals The set of globals to be passed to the sandbox +-- @function set_globals + local function set_globals(newglobals) globals = newglobals end diff --git a/lib/supple/sandbox.lua b/lib/supple/sandbox.lua index f4025bc..a6d9513 100644 --- a/lib/supple/sandbox.lua +++ b/lib/supple/sandbox.lua @@ -19,6 +19,17 @@ -- For licence terms, see COPYING -- +--- Running code in sandboxes +-- +-- This module is used by the sandbox code itself to start running sandboxed +-- Lua. The only entry point is invoked by the sandbox C wrapper during +-- startup. From here the sandbox locks itself down and then begins to listen +-- for work to do. +-- +-- You should only need to interact with this module if you are writing your +-- own Supple wrapper binary to use instead of the provided wrapper. +-- + local capi = require 'supple.capi' local objects = require 'supple.objects' local comms = require 'supple.comms' @@ -91,6 +102,14 @@ local function wrapped_unpack(t) return unpack(packed) end +--- Start the sandbox running +-- +-- This routine is invoked by the sandbox wrapper C code and starts the sandbox +-- running. Approximately it locks the sandbox down, including various limits +-- such as chroot, rlimits, dropping privileges, and seccomp mode if available. +-- Then it begins the main RPC loop for the sandbox. +-- +-- @function run local function run() -- Run the sandbox local result, errno = capi.lockdown() diff --git a/lib/supple/track.lua b/lib/supple/track.lua index b22156f..da8b37f 100644 --- a/lib/supple/track.lua +++ b/lib/supple/track.lua @@ -9,6 +9,22 @@ -- For licence terms, see COPYING -- +--- +-- Communications tracking for Supple sandboxes. +-- +-- This module provides a mechanism for keeping track of what goes on in the +-- communications path of a sandboxed runtime. The track is held from the +-- point of view of whichever side caused it to be recorded (typically the +-- host). Tracks are best generated by ensuring tracking is enabled and then +-- calling `supple.host.run`. Retrieval of the track afterwards is then +-- simple. +-- +-- supple.track.start() +-- supple.host.run(....) +-- print("Track:\n" .. supple.track.stop()) +-- + + local depth local track @@ -34,10 +50,27 @@ local function leave(...) end end +--- +-- Clear the track data and begin tracking. +-- +-- Call this routine to clear the current track data and begin tracking comms +-- and other Supple internals. +-- +-- @function start + local function start_tracking() depth, track = 0, {} end +--- +-- Stop tracking and return the current track. +-- +-- Assuming you have started tracking with `supple.track.start` you can call +-- this function to stop tracking and retrieve the track as a string. +-- +-- @treturn string The track data +-- @function stop + local function stop_tracking() if track == nil then return "***NO TRACKING DATA***" @@ -59,4 +92,4 @@ return { enter = enter, leave = leave, record = record, -}
\ No newline at end of file +} |