532 Commits

Author SHA1 Message Date
Michael Santos
0543904213 setrlimit: pass tuple to port
To be consistent with getrlimit, take a tuple representing the struct
rlimit as an argument.
2014-03-07 11:20:41 -05:00
Michael Santos
e8f6285d31 Fix tests 2014-03-07 10:53:40 -05:00
Michael Santos
1144b3e9b6 clone: increase the stack size
Increase the stack size. The child process would segfault when
allocating memory for the message.

Free the allocated memory in the parent. If the user calls clone/2,3
with the CLONE_VM flag, bad things will happen.
2014-03-07 10:17:08 -05:00
Michael Santos
9a0672126c Tunnel messages between forked processes
Begin layering headers so messages can be passed from:

    Erlang -> port -> child -> child
2014-03-07 09:54:02 -05:00
Michael Santos
9d30aecd29 WIP: proxy
Convert alcove to a select loop. Each process can call the commands.
fork(2) and clone(2) are now just commands.
2014-03-04 18:24:07 -05:00
Michael Santos
10f9818000 Add unshare(2) 2014-03-04 08:21:29 -05:00
Michael Santos
74d6e9e19d Expand options passed as list
[{ns,["ipc","net"]}] -> [{ns, "ipc"}, {ns, "net"}]
2014-03-03 13:05:41 -05:00
Michael Santos
984d860ec3 cleanup: remove fun for parent after fork 2014-03-03 12:45:32 -05:00
Michael Santos
784cbdfd31 Remove temp variables 2014-03-03 10:34:37 -05:00
Michael Santos
a8f555828b Rename recv/1,2 -> ctl/1.2 2014-03-03 09:48:43 -05:00
Michael Santos
3529121f00 Add user namespaces 2014-03-03 07:46:45 -05:00
Michael Santos
82c2a684d4 Move temp fd storage out of state 2014-03-03 07:36:05 -05:00
Michael Santos
920abbd5ab Store PID returned from clone(2) 2014-03-03 07:21:10 -05:00
Michael Santos
f4c58c1a62 Add gethostname(2)/sethostname(2) 2014-03-02 17:32:28 -05:00
Michael Santos
43bdf3405f Update typespecs 2014-03-02 17:06:31 -05:00
Michael Santos
bf0b13bfe0 Add getpid(2)
Create a test that runs the port process in a new PID namespace and
tests that the child process is PID 1.
2014-03-02 17:02:55 -05:00
Michael Santos
0adecc2a12 Add support for Linux namespaces using clone(2)
Ugly, ugly code yet it compiles and the tests pass. I declare success!

To start a port in a new namespace:

    % see clone(2) for CLONE_NEW* flags
    1> Port = alcove_drv:start([
            {ns, "ipc"},
            {ns, "net"},
            {ns, "uts"},
            {ns, "ns"},
            {ns, "pid"}
            ]).

    2> alcove:execvp(Port, "/sbin/ifconfig", ["/sbin/ifconfig", "-a"]).
    ok

    3> IF = alcove:stdout(Port).
    <<"lo        Link encap:Local Loopback  \n          LOOPBACK MTU:16436  Metric:1\n          RX packets:0 errors:0 droppe"...>>

TODO:
* figure out how to test this
* add  ifdef'ed support for user namespaces
* test fork() still works
2014-03-02 16:49:20 -05:00
Michael Santos
54be79ec8a Tests for execvp
Write data to and from the child process. Requires having busybox
installed. Update the typespecs.
2014-03-02 15:15:16 -05:00
Michael Santos
f6b2038f9e call/cast: support iolists 2014-03-02 15:14:50 -05:00
Michael Santos
82ebb214ac Add test for setrlimit 2014-03-02 14:49:57 -05:00
Michael Santos
5e2a239114 Add test for chdir 2014-03-02 14:43:17 -05:00
Michael Santos
700fa1bc67 Add tests for setgid and setuid 2014-03-02 14:40:58 -05:00
Michael Santos
fc72f1ad7d Add getcwd(3) 2014-03-02 14:36:41 -05:00
Michael Santos
184c103e12 Add getuid(2), getgid(2) 2014-03-02 14:29:33 -05:00
Michael Santos
04f93d22fe Begin adding typespecs 2014-03-02 12:56:15 -05:00
Michael Santos
742b7eccf0 alcove_drv:call/2,3: add timeout
Also comment some unused functions to silence dialyzer.
2014-03-02 12:55:16 -05:00
Michael Santos
cd9ccde26d execvp/3: return errno on failure 2014-03-02 12:54:13 -05:00
Michael Santos
4bdd92e9ec execvp/3: do not wait for response
Since exec(3) will never return, perform a cast and return true. Other
calls will still block on a response from the port.
2014-03-02 11:50:22 -05:00
Michael Santos
e863582f17 Set the receive functions to return immediately
Because the exec() functions will never return, alcove can't use a
blocking call. Until something better is worked out, return immediately
if nothing is in the mailbox.
2014-03-02 11:32:05 -05:00
Michael Santos
0ec29ccc3b Support setns(2)
Join Linux namespaces by specifiying the path to the processes'
namespace. Assuming a container is running on PID 13502, the path to the
net namespace will be: /proc/13502/ns/net

    1> Port = alcove_drv:start().
    #Port<0.1001>

    2> alcove:setns(Port, "/proc/13502/ns/net").
    true

    3> alcove:execvp(Port, "/sbin/ifconfig", ["/sbin/ifconfig", "-a"]).
    true

    4> alcove:stdout(Port,0).
    <<"eth0      Link encap:Ethernet  HWaddr ...">>

setns(2) actually provides 2 parameters: an fd and an allowed namespace
(CLONE_NEWUTS, CLONE_NEWIPC, CLONE_NEWNET).

The second parameter is used when an fd with an unknown namespace is
passed to the process and the user wants to connect to a specific
namespace. In the case of alcove, the fd is opened by the port, so
specifying the namespace is not supported.

If alcove supports calling setns(2) by fd instead of by path, the
interface will need to be changed.
2014-03-02 11:29:18 -05:00
Michael Santos
8f40d16eb1 Add support for setrlimit(2)/getrlimit(2) 2014-03-02 10:31:50 -05:00
Michael Santos
a9245bae00 alcove: sandbox for erlang ports
alcove acts a proxy between the Erlang VM and a forked process. It can
enforce restrictions on the child process, such as dropping privileges,
setting resource limits and chroot'ing.

The goal is to support Linux namespaces, seccomp mode and cgroups so
the port process can run in an application container.

alcove should be portable though and a subset of the features should
work on any unix, possibly even supporting the sandboxing mechanisms on
other platforms.
2014-03-02 08:59:33 -05:00