summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2015-11-02 14:00:11 +0000
committerDaniel Silverstone <dsilvers@digital-scurf.org>2015-11-02 14:00:11 +0000
commit356238f901e84171ceb8361ceb63e0c3444b31f7 (patch)
tree64d19533d92c90cf9d77bf4a543ccc1035cb14a3
parent968ec2e65eb4b1abcc4203c32d856c8097a87d1c (diff)
downloadsupple-356238f901e84171ceb8361ceb63e0c3444b31f7.tar.gz
Add user documentation. Skipping internal docs for now
-rw-r--r--lib/supple.lua10
-rw-r--r--lib/supple/host.lua84
-rw-r--r--lib/supple/sandbox.lua19
-rw-r--r--lib/supple/track.lua35
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
+}