-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathchrootex.erl
More file actions
77 lines (63 loc) · 2.27 KB
/
chrootex.erl
File metadata and controls
77 lines (63 loc) · 2.27 KB
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
77
%%% Copyright (c) 2014-2026, Michael Santos <michael.santos@gmail.com>
%%%
%%% Permission to use, copy, modify, and/or distribute this software for any
%%% purpose with or without fee is hereby granted, provided that the above
%%% copyright notice and this permission notice appear in all copies.
%%%
%%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
%%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
%%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
%%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
%%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
%%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
%%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-module(chrootex).
-include_lib("alcove/include/alcove.hrl").
-export([
start/0,
sandbox/1, sandbox/2
]).
start() ->
alcove_drv:start_link([{exec, "sudo"}]).
sandbox(Drv) ->
sandbox(Drv, ["/bin/busybox", "cat"]).
sandbox(Drv, Argv) ->
{Path, Arg0, Args} = argv(Argv),
{ok, Child} = alcove:fork(Drv, []),
setlimits(Drv, Child),
chroot(Drv, Child, Path),
drop_privs(Drv, Child, id()),
ok = alcove:execvp(Drv, [Child], Arg0, [Arg0, Args]),
Child.
argv([Arg0, Args]) ->
Path = filename:dirname(Arg0),
Progname = filename:join(["/", filename:basename(Arg0)]),
{Path, Progname, Args}.
setlimits(Drv, Child) ->
% Disable writing to files
ok = alcove:setrlimit(
Drv,
[Child],
rlimit_fsize,
#alcove_rlimit{cur = 0, max = 0}
),
% Limit to one process
ok = alcove:setrlimit(
Drv,
[Child],
rlimit_nproc,
#alcove_rlimit{cur = 1, max = 1}
),
% Disable opening new file descriptors
{ok, NFD} = alcove:getrlimit(Drv, [Child], rlimit_nofile),
ok = alcove:setrlimit(Drv, [Child], rlimit_nofile, #alcove_rlimit{
cur = NFD#alcove_rlimit.cur, max = NFD#alcove_rlimit.cur
}).
chroot(Drv, Child, Path) ->
ok = alcove:chroot(Drv, [Child], Path),
ok = alcove:chdir(Drv, [Child], "/").
drop_privs(Drv, Child, Id) ->
ok = alcove:setgid(Drv, [Child], Id),
ok = alcove:setuid(Drv, [Child], Id).
id() ->
16#f0000000 + rand:uniform(16#ffff).