Idea about implementing a SECCOMP alike mechanism in BEAM
Lukas Larsson
lukas@REDACTED
Wed Dec 11 08:38:38 CET 2019
Hello,
It has been a while since it was published but maybe you will find this
interesting: http://www.erlang.se/publications/xjobb/0109-naeser.pdf
Lukas
On Wed, Dec 11, 2019 at 6:07 AM Henrique Marcomini <henrique4win@REDACTED>
wrote:
> Hi,
>
> I've been working with erlang/elixir for the past year and I really miss
> SECCOMP like features in the BEAM. So I started an implementation based on
> https://github.com/erlang/otp and I wanted to know what you people think
> about
> it.
>
> The idea is to provide a way to blacklist/whitelist function calls on a
> process level, so for example if I'm evaluating human input for a
> calculation,
> I can guarantee that no other function except the ones that are necessary
> are
> called. Going further, in a case where my erlang cookie is leaked, I know
> that only a limited set of functions are callable using rpc or
> node.spawn/2.
>
> The way I envision it (and I'm implementing it) is adding a byte to the
> process struct with the following meaning:
>
> 0 1 2 3 4 5 6 7
> +-+-+-+-+-+-+-+-+
> |E|M|S|I|U|U|U|U|
> +-+-+-+-+-+-+-+-+
>
> Where:
> E -> Whether the mechanism is active (0:Off/1:On)
> M -> Operation Mode (0:Whitelist/1:Blacklist)
> S -> Disable Spawn (0:Can spawn new process/1:Cannot spawn new process)
> I -> Whether a child process will inherit the
> U -> Unused
>
> There are some implicit rule in this byte:
> - M,S, and I are unused whether E is set to 0
> - I is unused if S is set to 1
>
> I choosed to use a byte because bitwise operation are cheap and are the
> least
> expensive way I could think, and bitmasks can be combined in a meaningful
> way.
>
> The verification of this byte would occur at the apply function, so we
> can
> check the byte every time a function is called. To know which function is
> whitelisted/blacklisted I added an Eterm to the process struct. This Eterm
> is a
> NIL terminated list of tuples, each tuple contains two atoms representing
> the
> module name and the function name which is whitelisted/blacklisted.
>
> Probably a hashmap, or a binary tree of hashs would be quicker to search.
> But I don't know if there is any good low level way to introduce it without
> adding a lot of code to the code base.
>
> To implement process inherit capabilites, I added a verification on
> spawn,
> but there are some possible bypasses that would need to be treated latter
> on.
>
> For example:
>
>
> -------------------------------------------------------------------------------
>
> If there is a process running as a dynamic supervisor (P1), some other
> process (P2) may send a message to spawn some worker (P5) and the father
> process would be the supervisor (P1), which may not have the mechanism
> active.
>
> Diagram below:
>
>
> | |
> | P1 - Dynamic Supervisor | P2 (With active mechanism)
> V |
> =============== |
> | P3 | P4 V
> V V
>
> When P2 asks P1 to spawn a new worker, the diagram will look like the
> following:
>
>
> | |
> | P1 - Dynamic Supervisor | P2 (With active mechanism)
> V |
> =============== |
> | P3 | P4 | P5 V
> V V V
>
> Where P3, P4, and P5 are spawned with P1 as a parent, so it will not
> inherit
> any rules from P2. At this point P5 can execute any code and send a
> message to
> P2, bypassing the mechanism.
>
>
> -------------------------------------------------------------------------------
>
> On another case a process (P1) on Node 1 which is under this mechanism
> may
> spawn another process (P2) to Node 2, and then P1 spawns another process
> (P3)
> on Node 1. If process generated by spawns of other nodes are less secure
> than
> the process that called the spawn function, it will lead to privilege
> escalation.
>
> Diagram below:
>
> +---------------+ +---------------+
> | | | |
> | Node 1 | | Node 2 |
> | | | |
> | P1 | spawn/2 | |
> | ------------> -------------> --------+ |
> | calls | | | |
> | | | | P2 |
> | | | | |
> | P3 | spawn/2 | calls | |
> | <---------- <------------- <---------+ |
> | | | |
> +---------------+ +---------------+
>
> If P3 restrictions are less strict than P1, then P1 escalated privilege.
>
>
> -------------------------------------------------------------------------------
>
> The code that I'm working is at
> https://github.com/Supitto/OTP/tree/maint
> and it is built upon the maint branch. It still quite imature and have some
> edges to trim (I'm still figthing with allocations and Eterms). But if this
> idea is apreciated I will implement everything on the main branch. Also if
> you can think of some other scenario where this mechanism is defeated,
> please
> infome me :D
>
> Thanks,
>
> Henrique Almeida Marcomini
>
> Telegram -> @supitto
> IRC (freenode) -> Supitto
>
> Ps. The code on the repo may be not working (depends on the commit), but
> the
> idea is there.
>
> Pps. I made everything in ASCII so to see it properly use monospace fonts
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20191211/2072aa37/attachment.htm>
More information about the erlang-questions
mailing list