summaryrefslogtreecommitdiff
path: root/lib/supple/host.lua
blob: 1226d19dece64ef18fb1bf6889eb9c921ee25797 (plain)
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
-- lib/supple/host.lua
--
-- Sandbox (for) Untrusted Procedure Partitioning (in) Lua Engine
--
-- Management of the host side of Supple
--
-- Copyright 2012 Daniel Silverstone <dsilvers@digital-scurf.org>
--
-- For licence terms, see COPYING
--

local luxio = require 'luxio'
local subprocess = require 'luxio.subprocess'

local comms = require 'supple.comms'
local objects = require 'supple.objects'

local counter = 0

local function run_wrapper()
   local wrapperpath = "@@WRAPPER_BIN@@"
   -- START_TEST_SUPPLE
   wrapperpath = "./testwrapper"
   -- END_TEST_SUPPLE
   local fds = {}
   local ret, errno = luxio.socketpair(luxio.AF_UNIX, luxio.SOCK_STREAM,
				       luxio.PF_UNIX, fds)
   if ret ~= 0 then
      error("Unable to launch subprocess, could not prepare socketpair():"
	    .. luxio.strerror(errno))
   end
   local proc, msg = subprocess.spawn {
      "supple-sandbox",
      exe = wrapperpath,
      stdin = fds[1],
--      stdout = fds[1],
--      stderr = fds[1],
   }
   if not proc then
      error(msg)
   end
   luxio.close(fds[1])
   return proc, fds[2]
end

local function run_sandbox(codestr, codename, ...)
   -- Prepare and start a sandbox,
   -- compiling the codestr and running it
   -- with the given args
   local child, commsfd = run_wrapper()

   counter = counter + 1
   objects.set_name(("host-%d"):format(counter))
   comms._set_fd(commsfd)
   objects.set_proc_call(comms.call)
   
   local func, err = comms.call("supple:loadstring", "__call", codestr, codename)
   if not func then
      error(err)
   end

   local ret = {func(...)}
   
   -- We need to clean up, so dump all the objects
   func = nil
   objects.clean_down()

   comms._set_fd(-1)
   luxio.kill(child.pid, luxio.SIGKILL)
   child:wait()
   return unpack(ret)
end

return {
   run = run_sandbox,
}