Site update

This commit is contained in:
Ryan Voots 2017-10-23 12:25:27 -07:00
parent 224a442800
commit 82a2d5f717
13 changed files with 1412 additions and 6 deletions

View file

@ -76,6 +76,8 @@ and perform an action on it.</p>
<nav id="tags">
<h1>Tags</h1>
<ul class="list-inline">
<li><a href="/blog/tag/evalserver/">evalserver</a></li>
<li><a href="/blog/tag/seccomp/">seccomp</a></li>
</ul>
</nav>

View file

@ -67,9 +67,9 @@ directory on the root filesystem. This was done to make getting them to work in
</a>
</li>
<li class="next">
<button disabled>
<a class="button button-primary" href="/blog/2017/10/10/seccomp-and-you/index.html" rel="next">
Newer →
</button>
</a>
</li>
</ul>
@ -83,6 +83,8 @@ directory on the root filesystem. This was done to make getting them to work in
<nav id="tags">
<h1>Tags</h1>
<ul class="list-inline">
<li><a href="/blog/tag/evalserver/">evalserver</a></li>
<li><a href="/blog/tag/seccomp/">seccomp</a></li>
</ul>
</nav>

View file

@ -0,0 +1,184 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1" name="viewport">
<link href="/theme/css/normalize.css" rel="stylesheet">
<link href="/theme/css/skeleton.css" rel="stylesheet">
<link href="/theme/css/statocles-default.css" rel="stylesheet">
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
<title>Seccomp and you - Perlbot.pl pastebin</title>
<meta content="Statocles 0.086" name="generator">
</head>
<body>
<header>
<nav class="navbar">
<div class="container">
<a class="brand" href="/">Perlbot.pl pastebin</a>
<ul>
<li>
<a href="/blog">Blog</a>
</li>
</ul>
</div>
</nav>
</header>
<div class="main container">
<div class="row">
<div class="nine columns">
<main>
<header>
<h1>Seccomp and you</h1>
<aside>
<time datetime="2017-10-10">
Posted on 2017-10-10
</time>
</aside>
<p class="tags">Tags:
<a href="/blog/tag/evalserver/" rel="tag">evalserver</a>
<a href="/blog/tag/seccomp/" rel="tag">seccomp</a>
</p>
</header>
<section id="section-1">
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
(heretofore refered to as seccomp).</p>
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
systrace—which seems to be no longer supported for Linux).
-- https://en.wikipedia.org/wiki/Seccomp
</code></pre>
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
predefined rules, organized into &#39;profiles&#39;. Each profile is intended to represent a
single kind of action that a program could do, such as open a file for reading, open a
file for writing, etc.</p>
<p>I&#39;ve created a few profiles to start with</p>
<ul>
<li><p>stdio
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
<li><p>file_open
Allows calling some file related system calls, such as: open, openat, close, select,
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it&#39;s a
tty. The flags that are allowed to go to a opening a file are defined in the &quot;open_modes&quot;
rules that will be covered later</p></li>
<li><p>file_opendir
Allows opening a directory to get a list of files, and also includes the file_open
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
or similar programs</p></li>
<li><p>file_tty
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
<li><p>file_readonly
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
similar calls</p></li>
<li><p>file_write
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
<li><p>time_calls
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
<li><p>ruby_timer_thread
This one is a special ruby specific profile. It allows ruby to create a thread that
it uses internally, and only allows that thread creation with a specific set of flags,
CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
to run. It also allows for pipe2 to be called to create communication between the two
threads.</p></li>
<li><p>perl_file_temp
This was added specifically for behavior of File::Temp, and might get folded into a
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
<li><p>exec_wrapper
This one is seriously special. It&#39;s not a predefined set of rules, but in fact
generates the rules at runtime. This is because of limitations of seccomp. Since
seccomp can&#39;t inspect inside of pointers, there&#39;s no way to verify the contents of a
string being passed to execve(), instead we create a white-list of strings that can be
passed to it, and only allow calls to execve that are passed pointers to this syscall.
This isn&#39;t perfectly secure since someone could overwrite the contents at a later point
but it&#39;s safe enough because an attacker can&#39;t view the generated BPF to extract the
addresses, and the strings themselves should be gone from memory by the time their code
runs, preventing them from recreating the original addresses. This requires ASLR in order
to be effective at preventing an attacker from derriving the address of the strings from
previous runs.</p></li>
</ul>
<p>There&#39;s also some other profiles like ruby_timer_thread specifically for allowing node.js
to do similar things to ruby (create a thread, use epoll, etc.).</p>
<p>=== Handling flags to syscalls</p>
<p>The way the rules are defined allow syscalls like open() to not need special handling.
Since many syscalls can take flags, it&#39;s useful to be able to limit the flags they can
take.</p>
<p>{syscall =&gt; &#39;openat&#39;, permute_rules =&gt; [[&#39;2&#39;, &#39;==&#39;, \&#39;open_modes&#39;]]},</p>
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
automatically generated rules from a permutation. In this cases it&#39;s called &#39;open_modes&#39;.
A profile can add (but not remove) values to the permutation rules, and then when the
whole BPF program gets compiled it&#39;ll generate all the applicable rules for you. This
makes setting up calls like open much much simpler since you don&#39;t have to write out all
possible modes yourself. This is also an area where I could be doing better to optimize
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
operations that could make this more effective but they were not well exposed through
Linux::Seccomp when this was originally designed.</p>
<p>In the second part of this blog I&#39;ll document the proposed configuration
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
</section>
<ul class="pager">
<li class="prev">
<a class="button button-primary" href="/blog/2017/10/02/new-old-perls/index.html" rel="prev">
← Older
</a>
</li>
<li class="next">
<button disabled>
Newer →
</button>
</li>
</ul>
</main>
</div>
<div class="three columns sidebar">
<nav id="tags">
<h1>Tags</h1>
<ul class="list-inline">
<li><a href="/blog/tag/evalserver/">evalserver</a></li>
<li><a href="/blog/tag/seccomp/">seccomp</a></li>
</ul>
</nav>
</div>
</div>
</div>
<footer>
<div class="container tagline">
<a href="http://preaction.me/statocles">Made with Statocles</a><br>
<a href="http://www.perl.org">Powered by Perl</a>
</div>
</footer>
</body>
</html>

View file

@ -2,11 +2,117 @@
<feed xmlns="http://www.w3.org/2005/Atom">
<id>https://perlbot.pl/blog/</id>
<title>Perlbot.pl pastebin</title>
<updated>2017-10-02T00:00:00Z</updated>
<updated>2017-10-10T00:00:00Z</updated>
<link href="https://perlbot.pl/blog/index.atom" rel="self" />
<link href="https://perlbot.pl/blog/" rel="alternate" />
<generator version="0.086">Statocles</generator>
<entry>
<id>https://perlbot.pl/blog/2017/10/10/seccomp-and-you/</id>
<title>Seccomp and you</title>
<link href="https://perlbot.pl/blog/2017/10/10/seccomp-and-you/" rel="alternate" />
<content type="html"><![CDATA[
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
(heretofore refered to as seccomp).</p>
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
systrace—which seems to be no longer supported for Linux).
-- https://en.wikipedia.org/wiki/Seccomp
</code></pre>
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
predefined rules, organized into &#39;profiles&#39;. Each profile is intended to represent a
single kind of action that a program could do, such as open a file for reading, open a
file for writing, etc.</p>
<p>I&#39;ve created a few profiles to start with</p>
<ul>
<li><p>stdio
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
<li><p>file_open
Allows calling some file related system calls, such as: open, openat, close, select,
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it&#39;s a
tty. The flags that are allowed to go to a opening a file are defined in the &quot;open_modes&quot;
rules that will be covered later</p></li>
<li><p>file_opendir
Allows opening a directory to get a list of files, and also includes the file_open
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
or similar programs</p></li>
<li><p>file_tty
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
<li><p>file_readonly
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
similar calls</p></li>
<li><p>file_write
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
<li><p>time_calls
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
<li><p>ruby_timer_thread
This one is a special ruby specific profile. It allows ruby to create a thread that
it uses internally, and only allows that thread creation with a specific set of flags,
CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
to run. It also allows for pipe2 to be called to create communication between the two
threads.</p></li>
<li><p>perl_file_temp
This was added specifically for behavior of File::Temp, and might get folded into a
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
<li><p>exec_wrapper
This one is seriously special. It&#39;s not a predefined set of rules, but in fact
generates the rules at runtime. This is because of limitations of seccomp. Since
seccomp can&#39;t inspect inside of pointers, there&#39;s no way to verify the contents of a
string being passed to execve(), instead we create a white-list of strings that can be
passed to it, and only allow calls to execve that are passed pointers to this syscall.
This isn&#39;t perfectly secure since someone could overwrite the contents at a later point
but it&#39;s safe enough because an attacker can&#39;t view the generated BPF to extract the
addresses, and the strings themselves should be gone from memory by the time their code
runs, preventing them from recreating the original addresses. This requires ASLR in order
to be effective at preventing an attacker from derriving the address of the strings from
previous runs.</p></li>
</ul>
<p>There&#39;s also some other profiles like ruby_timer_thread specifically for allowing node.js
to do similar things to ruby (create a thread, use epoll, etc.).</p>
<p>=== Handling flags to syscalls</p>
<p>The way the rules are defined allow syscalls like open() to not need special handling.
Since many syscalls can take flags, it&#39;s useful to be able to limit the flags they can
take.</p>
<p>{syscall =&gt; &#39;openat&#39;, permute_rules =&gt; [[&#39;2&#39;, &#39;==&#39;, \&#39;open_modes&#39;]]},</p>
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
automatically generated rules from a permutation. In this cases it&#39;s called &#39;open_modes&#39;.
A profile can add (but not remove) values to the permutation rules, and then when the
whole BPF program gets compiled it&#39;ll generate all the applicable rules for you. This
makes setting up calls like open much much simpler since you don&#39;t have to write out all
possible modes yourself. This is also an area where I could be doing better to optimize
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
operations that could make this more effective but they were not well exposed through
Linux::Seccomp when this was originally designed.</p>
<p>In the second part of this blog I&#39;ll document the proposed configuration
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
<p>Tags:
<a href="https://perlbot.pl/blog/tag/evalserver/">evalserver</a>
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
</p>
]]></content>
<updated>2017-10-10T00:00:00Z</updated>
<category term="evalserver" />
<category term="seccomp" />
</entry>
<entry>
<id>https://perlbot.pl/blog/2017/10/02/new-old-perls/</id>
<title>New old perls</title>

View file

@ -34,6 +34,116 @@
<main>
<article>
<header>
<h1><a href="/blog/2017/10/10/seccomp-and-you/">Seccomp and you</a></h1>
<aside>
<time datetime="2017-10-10">
Posted on 2017-10-10
</time>
</aside>
<p class="tags">Tags:
<a href="/blog/tag/evalserver/" rel="tag">evalserver</a>
<a href="/blog/tag/seccomp/" rel="tag">seccomp</a>
</p>
</header>
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
(heretofore refered to as seccomp).</p>
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
systrace—which seems to be no longer supported for Linux).
-- https://en.wikipedia.org/wiki/Seccomp
</code></pre>
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
predefined rules, organized into &#39;profiles&#39;. Each profile is intended to represent a
single kind of action that a program could do, such as open a file for reading, open a
file for writing, etc.</p>
<p>I&#39;ve created a few profiles to start with</p>
<ul>
<li><p>stdio
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
<li><p>file_open
Allows calling some file related system calls, such as: open, openat, close, select,
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it&#39;s a
tty. The flags that are allowed to go to a opening a file are defined in the &quot;open_modes&quot;
rules that will be covered later</p></li>
<li><p>file_opendir
Allows opening a directory to get a list of files, and also includes the file_open
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
or similar programs</p></li>
<li><p>file_tty
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
<li><p>file_readonly
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
similar calls</p></li>
<li><p>file_write
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
<li><p>time_calls
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
<li><p>ruby_timer_thread
This one is a special ruby specific profile. It allows ruby to create a thread that
it uses internally, and only allows that thread creation with a specific set of flags,
CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
to run. It also allows for pipe2 to be called to create communication between the two
threads.</p></li>
<li><p>perl_file_temp
This was added specifically for behavior of File::Temp, and might get folded into a
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
<li><p>exec_wrapper
This one is seriously special. It&#39;s not a predefined set of rules, but in fact
generates the rules at runtime. This is because of limitations of seccomp. Since
seccomp can&#39;t inspect inside of pointers, there&#39;s no way to verify the contents of a
string being passed to execve(), instead we create a white-list of strings that can be
passed to it, and only allow calls to execve that are passed pointers to this syscall.
This isn&#39;t perfectly secure since someone could overwrite the contents at a later point
but it&#39;s safe enough because an attacker can&#39;t view the generated BPF to extract the
addresses, and the strings themselves should be gone from memory by the time their code
runs, preventing them from recreating the original addresses. This requires ASLR in order
to be effective at preventing an attacker from derriving the address of the strings from
previous runs.</p></li>
</ul>
<p>There&#39;s also some other profiles like ruby_timer_thread specifically for allowing node.js
to do similar things to ruby (create a thread, use epoll, etc.).</p>
<p>=== Handling flags to syscalls</p>
<p>The way the rules are defined allow syscalls like open() to not need special handling.
Since many syscalls can take flags, it&#39;s useful to be able to limit the flags they can
take.</p>
<p>{syscall =&gt; &#39;openat&#39;, permute_rules =&gt; [[&#39;2&#39;, &#39;==&#39;, \&#39;open_modes&#39;]]},</p>
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
automatically generated rules from a permutation. In this cases it&#39;s called &#39;open_modes&#39;.
A profile can add (but not remove) values to the permutation rules, and then when the
whole BPF program gets compiled it&#39;ll generate all the applicable rules for you. This
makes setting up calls like open much much simpler since you don&#39;t have to write out all
possible modes yourself. This is also an area where I could be doing better to optimize
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
operations that could make this more effective but they were not well exposed through
Linux::Seccomp when this was originally designed.</p>
<p>In the second part of this blog I&#39;ll document the proposed configuration
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
</article>
<article>
<header>
<h1><a href="/blog/2017/10/02/new-old-perls/">New old perls</a></h1>
@ -114,6 +224,8 @@ and perform an action on it.</p>
<nav id="tags">
<h1>Tags</h1>
<ul class="list-inline">
<li><a href="/blog/tag/evalserver/">evalserver</a></li>
<li><a href="/blog/tag/seccomp/">seccomp</a></li>
</ul>
</nav>

View file

@ -6,6 +6,112 @@
<atom:link href="https://perlbot.pl/blog/index.rss" rel="self" type="application/rss+xml" />
<description>Blog feed of Perlbot.pl pastebin</description>
<generator>Statocles 0.086</generator>
<item>
<title>Seccomp and you</title>
<link>https://perlbot.pl/blog/2017/10/10/seccomp-and-you/</link>
<guid>https://perlbot.pl/blog/2017/10/10/seccomp-and-you/</guid>
<description><![CDATA[
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
(heretofore refered to as seccomp).</p>
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
systrace—which seems to be no longer supported for Linux).
-- https://en.wikipedia.org/wiki/Seccomp
</code></pre>
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
predefined rules, organized into &#39;profiles&#39;. Each profile is intended to represent a
single kind of action that a program could do, such as open a file for reading, open a
file for writing, etc.</p>
<p>I&#39;ve created a few profiles to start with</p>
<ul>
<li><p>stdio
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
<li><p>file_open
Allows calling some file related system calls, such as: open, openat, close, select,
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it&#39;s a
tty. The flags that are allowed to go to a opening a file are defined in the &quot;open_modes&quot;
rules that will be covered later</p></li>
<li><p>file_opendir
Allows opening a directory to get a list of files, and also includes the file_open
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
or similar programs</p></li>
<li><p>file_tty
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
<li><p>file_readonly
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
similar calls</p></li>
<li><p>file_write
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
<li><p>time_calls
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
<li><p>ruby_timer_thread
This one is a special ruby specific profile. It allows ruby to create a thread that
it uses internally, and only allows that thread creation with a specific set of flags,
CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
to run. It also allows for pipe2 to be called to create communication between the two
threads.</p></li>
<li><p>perl_file_temp
This was added specifically for behavior of File::Temp, and might get folded into a
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
<li><p>exec_wrapper
This one is seriously special. It&#39;s not a predefined set of rules, but in fact
generates the rules at runtime. This is because of limitations of seccomp. Since
seccomp can&#39;t inspect inside of pointers, there&#39;s no way to verify the contents of a
string being passed to execve(), instead we create a white-list of strings that can be
passed to it, and only allow calls to execve that are passed pointers to this syscall.
This isn&#39;t perfectly secure since someone could overwrite the contents at a later point
but it&#39;s safe enough because an attacker can&#39;t view the generated BPF to extract the
addresses, and the strings themselves should be gone from memory by the time their code
runs, preventing them from recreating the original addresses. This requires ASLR in order
to be effective at preventing an attacker from derriving the address of the strings from
previous runs.</p></li>
</ul>
<p>There&#39;s also some other profiles like ruby_timer_thread specifically for allowing node.js
to do similar things to ruby (create a thread, use epoll, etc.).</p>
<p>=== Handling flags to syscalls</p>
<p>The way the rules are defined allow syscalls like open() to not need special handling.
Since many syscalls can take flags, it&#39;s useful to be able to limit the flags they can
take.</p>
<p>{syscall =&gt; &#39;openat&#39;, permute_rules =&gt; [[&#39;2&#39;, &#39;==&#39;, \&#39;open_modes&#39;]]},</p>
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
automatically generated rules from a permutation. In this cases it&#39;s called &#39;open_modes&#39;.
A profile can add (but not remove) values to the permutation rules, and then when the
whole BPF program gets compiled it&#39;ll generate all the applicable rules for you. This
makes setting up calls like open much much simpler since you don&#39;t have to write out all
possible modes yourself. This is also an area where I could be doing better to optimize
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
operations that could make this more effective but they were not well exposed through
Linux::Seccomp when this was originally designed.</p>
<p>In the second part of this blog I&#39;ll document the proposed configuration
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
<p>Tags:
<a href="https://perlbot.pl/blog/tag/evalserver/">evalserver</a>
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
</p>
]]></description>
<pubDate>
Tue, 10 Oct 2017 00:00:00 +0000
</pubDate>
</item>
<item>
<title>New old perls</title>
<link>https://perlbot.pl/blog/2017/10/02/new-old-perls/</link>

117
blog/tag/evalserver.atom Normal file
View file

@ -0,0 +1,117 @@
<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<id>https://perlbot.pl/blog/tag/evalserver/</id>
<title>Perlbot.pl pastebin</title>
<updated>2017-10-10T00:00:00Z</updated>
<link href="https://perlbot.pl/blog/tag/evalserver.atom" rel="self" />
<link href="https://perlbot.pl/blog/tag/evalserver/" rel="alternate" />
<generator version="0.086">Statocles</generator>
<entry>
<id>https://perlbot.pl/blog/2017/10/10/seccomp-and-you/</id>
<title>Seccomp and you</title>
<link href="https://perlbot.pl/blog/2017/10/10/seccomp-and-you/" rel="alternate" />
<content type="html"><![CDATA[
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
(heretofore refered to as seccomp).</p>
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
systrace—which seems to be no longer supported for Linux).
-- https://en.wikipedia.org/wiki/Seccomp
</code></pre>
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
predefined rules, organized into &#39;profiles&#39;. Each profile is intended to represent a
single kind of action that a program could do, such as open a file for reading, open a
file for writing, etc.</p>
<p>I&#39;ve created a few profiles to start with</p>
<ul>
<li><p>stdio
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
<li><p>file_open
Allows calling some file related system calls, such as: open, openat, close, select,
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it&#39;s a
tty. The flags that are allowed to go to a opening a file are defined in the &quot;open_modes&quot;
rules that will be covered later</p></li>
<li><p>file_opendir
Allows opening a directory to get a list of files, and also includes the file_open
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
or similar programs</p></li>
<li><p>file_tty
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
<li><p>file_readonly
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
similar calls</p></li>
<li><p>file_write
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
<li><p>time_calls
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
<li><p>ruby_timer_thread
This one is a special ruby specific profile. It allows ruby to create a thread that
it uses internally, and only allows that thread creation with a specific set of flags,
CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
to run. It also allows for pipe2 to be called to create communication between the two
threads.</p></li>
<li><p>perl_file_temp
This was added specifically for behavior of File::Temp, and might get folded into a
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
<li><p>exec_wrapper
This one is seriously special. It&#39;s not a predefined set of rules, but in fact
generates the rules at runtime. This is because of limitations of seccomp. Since
seccomp can&#39;t inspect inside of pointers, there&#39;s no way to verify the contents of a
string being passed to execve(), instead we create a white-list of strings that can be
passed to it, and only allow calls to execve that are passed pointers to this syscall.
This isn&#39;t perfectly secure since someone could overwrite the contents at a later point
but it&#39;s safe enough because an attacker can&#39;t view the generated BPF to extract the
addresses, and the strings themselves should be gone from memory by the time their code
runs, preventing them from recreating the original addresses. This requires ASLR in order
to be effective at preventing an attacker from derriving the address of the strings from
previous runs.</p></li>
</ul>
<p>There&#39;s also some other profiles like ruby_timer_thread specifically for allowing node.js
to do similar things to ruby (create a thread, use epoll, etc.).</p>
<p>=== Handling flags to syscalls</p>
<p>The way the rules are defined allow syscalls like open() to not need special handling.
Since many syscalls can take flags, it&#39;s useful to be able to limit the flags they can
take.</p>
<p>{syscall =&gt; &#39;openat&#39;, permute_rules =&gt; [[&#39;2&#39;, &#39;==&#39;, \&#39;open_modes&#39;]]},</p>
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
automatically generated rules from a permutation. In this cases it&#39;s called &#39;open_modes&#39;.
A profile can add (but not remove) values to the permutation rules, and then when the
whole BPF program gets compiled it&#39;ll generate all the applicable rules for you. This
makes setting up calls like open much much simpler since you don&#39;t have to write out all
possible modes yourself. This is also an area where I could be doing better to optimize
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
operations that could make this more effective but they were not well exposed through
Linux::Seccomp when this was originally designed.</p>
<p>In the second part of this blog I&#39;ll document the proposed configuration
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
<p>Tags:
<a href="https://perlbot.pl/blog/tag/evalserver/">evalserver</a>
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
</p>
]]></content>
<updated>2017-10-10T00:00:00Z</updated>
<category term="evalserver" />
<category term="seccomp" />
</entry>
</feed>

117
blog/tag/evalserver.rss Normal file
View file

@ -0,0 +1,117 @@
<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Perlbot.pl pastebin</title>
<link>https://perlbot.pl/blog/tag/evalserver/</link>
<atom:link href="https://perlbot.pl/blog/tag/evalserver.rss" rel="self" type="application/rss+xml" />
<description>Blog feed of Perlbot.pl pastebin</description>
<generator>Statocles 0.086</generator>
<item>
<title>Seccomp and you</title>
<link>https://perlbot.pl/blog/2017/10/10/seccomp-and-you/</link>
<guid>https://perlbot.pl/blog/2017/10/10/seccomp-and-you/</guid>
<description><![CDATA[
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
(heretofore refered to as seccomp).</p>
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
systrace—which seems to be no longer supported for Linux).
-- https://en.wikipedia.org/wiki/Seccomp
</code></pre>
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
predefined rules, organized into &#39;profiles&#39;. Each profile is intended to represent a
single kind of action that a program could do, such as open a file for reading, open a
file for writing, etc.</p>
<p>I&#39;ve created a few profiles to start with</p>
<ul>
<li><p>stdio
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
<li><p>file_open
Allows calling some file related system calls, such as: open, openat, close, select,
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it&#39;s a
tty. The flags that are allowed to go to a opening a file are defined in the &quot;open_modes&quot;
rules that will be covered later</p></li>
<li><p>file_opendir
Allows opening a directory to get a list of files, and also includes the file_open
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
or similar programs</p></li>
<li><p>file_tty
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
<li><p>file_readonly
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
similar calls</p></li>
<li><p>file_write
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
<li><p>time_calls
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
<li><p>ruby_timer_thread
This one is a special ruby specific profile. It allows ruby to create a thread that
it uses internally, and only allows that thread creation with a specific set of flags,
CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
to run. It also allows for pipe2 to be called to create communication between the two
threads.</p></li>
<li><p>perl_file_temp
This was added specifically for behavior of File::Temp, and might get folded into a
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
<li><p>exec_wrapper
This one is seriously special. It&#39;s not a predefined set of rules, but in fact
generates the rules at runtime. This is because of limitations of seccomp. Since
seccomp can&#39;t inspect inside of pointers, there&#39;s no way to verify the contents of a
string being passed to execve(), instead we create a white-list of strings that can be
passed to it, and only allow calls to execve that are passed pointers to this syscall.
This isn&#39;t perfectly secure since someone could overwrite the contents at a later point
but it&#39;s safe enough because an attacker can&#39;t view the generated BPF to extract the
addresses, and the strings themselves should be gone from memory by the time their code
runs, preventing them from recreating the original addresses. This requires ASLR in order
to be effective at preventing an attacker from derriving the address of the strings from
previous runs.</p></li>
</ul>
<p>There&#39;s also some other profiles like ruby_timer_thread specifically for allowing node.js
to do similar things to ruby (create a thread, use epoll, etc.).</p>
<p>=== Handling flags to syscalls</p>
<p>The way the rules are defined allow syscalls like open() to not need special handling.
Since many syscalls can take flags, it&#39;s useful to be able to limit the flags they can
take.</p>
<p>{syscall =&gt; &#39;openat&#39;, permute_rules =&gt; [[&#39;2&#39;, &#39;==&#39;, \&#39;open_modes&#39;]]},</p>
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
automatically generated rules from a permutation. In this cases it&#39;s called &#39;open_modes&#39;.
A profile can add (but not remove) values to the permutation rules, and then when the
whole BPF program gets compiled it&#39;ll generate all the applicable rules for you. This
makes setting up calls like open much much simpler since you don&#39;t have to write out all
possible modes yourself. This is also an area where I could be doing better to optimize
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
operations that could make this more effective but they were not well exposed through
Linux::Seccomp when this was originally designed.</p>
<p>In the second part of this blog I&#39;ll document the proposed configuration
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
<p>Tags:
<a href="https://perlbot.pl/blog/tag/evalserver/">evalserver</a>
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
</p>
]]></description>
<pubDate>
Tue, 10 Oct 2017 00:00:00 +0000
</pubDate>
</item>
</channel>
</rss>

View file

@ -0,0 +1,204 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1" name="viewport">
<link href="/theme/css/normalize.css" rel="stylesheet">
<link href="/theme/css/skeleton.css" rel="stylesheet">
<link href="/theme/css/statocles-default.css" rel="stylesheet">
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
<title>Perlbot.pl pastebin</title>
<meta content="Statocles 0.086" name="generator">
<link href="/blog/tag/evalserver.atom" rel="alternate" type="application/atom+xml">
<link href="/blog/tag/evalserver.rss" rel="alternate" type="application/rss+xml">
</head>
<body>
<header>
<nav class="navbar">
<div class="container">
<a class="brand" href="/">Perlbot.pl pastebin</a>
<ul>
<li>
<a href="/blog">Blog</a>
</li>
</ul>
</div>
</nav>
</header>
<div class="main container">
<div class="row">
<div class="nine columns">
<main>
<article>
<header>
<h1><a href="/blog/2017/10/10/seccomp-and-you/">Seccomp and you</a></h1>
<aside>
<time datetime="2017-10-10">
Posted on 2017-10-10
</time>
</aside>
<p class="tags">Tags:
<a href="/blog/tag/evalserver/" rel="tag">evalserver</a>
<a href="/blog/tag/seccomp/" rel="tag">seccomp</a>
</p>
</header>
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
(heretofore refered to as seccomp).</p>
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
systrace—which seems to be no longer supported for Linux).
-- https://en.wikipedia.org/wiki/Seccomp
</code></pre>
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
predefined rules, organized into &#39;profiles&#39;. Each profile is intended to represent a
single kind of action that a program could do, such as open a file for reading, open a
file for writing, etc.</p>
<p>I&#39;ve created a few profiles to start with</p>
<ul>
<li><p>stdio
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
<li><p>file_open
Allows calling some file related system calls, such as: open, openat, close, select,
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it&#39;s a
tty. The flags that are allowed to go to a opening a file are defined in the &quot;open_modes&quot;
rules that will be covered later</p></li>
<li><p>file_opendir
Allows opening a directory to get a list of files, and also includes the file_open
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
or similar programs</p></li>
<li><p>file_tty
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
<li><p>file_readonly
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
similar calls</p></li>
<li><p>file_write
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
<li><p>time_calls
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
<li><p>ruby_timer_thread
This one is a special ruby specific profile. It allows ruby to create a thread that
it uses internally, and only allows that thread creation with a specific set of flags,
CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
to run. It also allows for pipe2 to be called to create communication between the two
threads.</p></li>
<li><p>perl_file_temp
This was added specifically for behavior of File::Temp, and might get folded into a
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
<li><p>exec_wrapper
This one is seriously special. It&#39;s not a predefined set of rules, but in fact
generates the rules at runtime. This is because of limitations of seccomp. Since
seccomp can&#39;t inspect inside of pointers, there&#39;s no way to verify the contents of a
string being passed to execve(), instead we create a white-list of strings that can be
passed to it, and only allow calls to execve that are passed pointers to this syscall.
This isn&#39;t perfectly secure since someone could overwrite the contents at a later point
but it&#39;s safe enough because an attacker can&#39;t view the generated BPF to extract the
addresses, and the strings themselves should be gone from memory by the time their code
runs, preventing them from recreating the original addresses. This requires ASLR in order
to be effective at preventing an attacker from derriving the address of the strings from
previous runs.</p></li>
</ul>
<p>There&#39;s also some other profiles like ruby_timer_thread specifically for allowing node.js
to do similar things to ruby (create a thread, use epoll, etc.).</p>
<p>=== Handling flags to syscalls</p>
<p>The way the rules are defined allow syscalls like open() to not need special handling.
Since many syscalls can take flags, it&#39;s useful to be able to limit the flags they can
take.</p>
<p>{syscall =&gt; &#39;openat&#39;, permute_rules =&gt; [[&#39;2&#39;, &#39;==&#39;, \&#39;open_modes&#39;]]},</p>
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
automatically generated rules from a permutation. In this cases it&#39;s called &#39;open_modes&#39;.
A profile can add (but not remove) values to the permutation rules, and then when the
whole BPF program gets compiled it&#39;ll generate all the applicable rules for you. This
makes setting up calls like open much much simpler since you don&#39;t have to write out all
possible modes yourself. This is also an area where I could be doing better to optimize
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
operations that could make this more effective but they were not well exposed through
Linux::Seccomp when this was originally designed.</p>
<p>In the second part of this blog I&#39;ll document the proposed configuration
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
</article>
<ul class="pager">
<li class="prev">
<button disabled>
← Older
</button>
</li>
<li class="next">
<button disabled>
Newer →
</button>
</li>
</ul>
</main>
</div>
<div class="three columns sidebar">
<nav id="tags">
<h1>Tags</h1>
<ul class="list-inline">
<li><a href="/blog/tag/evalserver/">evalserver</a></li>
<li><a href="/blog/tag/seccomp/">seccomp</a></li>
</ul>
</nav>
<h1>Feeds</h1>
<ul class="list-inline">
<li>
<a href="/blog/tag/evalserver.atom" rel="alternate" type="application/atom+xml">
Atom
</a>
</li>
<li>
<a href="/blog/tag/evalserver.rss" rel="alternate" type="application/rss+xml">
RSS
</a>
</li>
</ul>
</div>
</div>
</div>
<footer>
<div class="container tagline">
<a href="http://preaction.me/statocles">Made with Statocles</a><br>
<a href="http://www.perl.org">Powered by Perl</a>
</div>
</footer>
</body>
</html>

117
blog/tag/seccomp.atom Normal file
View file

@ -0,0 +1,117 @@
<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<id>https://perlbot.pl/blog/tag/seccomp/</id>
<title>Perlbot.pl pastebin</title>
<updated>2017-10-10T00:00:00Z</updated>
<link href="https://perlbot.pl/blog/tag/seccomp.atom" rel="self" />
<link href="https://perlbot.pl/blog/tag/seccomp/" rel="alternate" />
<generator version="0.086">Statocles</generator>
<entry>
<id>https://perlbot.pl/blog/2017/10/10/seccomp-and-you/</id>
<title>Seccomp and you</title>
<link href="https://perlbot.pl/blog/2017/10/10/seccomp-and-you/" rel="alternate" />
<content type="html"><![CDATA[
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
(heretofore refered to as seccomp).</p>
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
systrace—which seems to be no longer supported for Linux).
-- https://en.wikipedia.org/wiki/Seccomp
</code></pre>
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
predefined rules, organized into &#39;profiles&#39;. Each profile is intended to represent a
single kind of action that a program could do, such as open a file for reading, open a
file for writing, etc.</p>
<p>I&#39;ve created a few profiles to start with</p>
<ul>
<li><p>stdio
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
<li><p>file_open
Allows calling some file related system calls, such as: open, openat, close, select,
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it&#39;s a
tty. The flags that are allowed to go to a opening a file are defined in the &quot;open_modes&quot;
rules that will be covered later</p></li>
<li><p>file_opendir
Allows opening a directory to get a list of files, and also includes the file_open
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
or similar programs</p></li>
<li><p>file_tty
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
<li><p>file_readonly
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
similar calls</p></li>
<li><p>file_write
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
<li><p>time_calls
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
<li><p>ruby_timer_thread
This one is a special ruby specific profile. It allows ruby to create a thread that
it uses internally, and only allows that thread creation with a specific set of flags,
CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
to run. It also allows for pipe2 to be called to create communication between the two
threads.</p></li>
<li><p>perl_file_temp
This was added specifically for behavior of File::Temp, and might get folded into a
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
<li><p>exec_wrapper
This one is seriously special. It&#39;s not a predefined set of rules, but in fact
generates the rules at runtime. This is because of limitations of seccomp. Since
seccomp can&#39;t inspect inside of pointers, there&#39;s no way to verify the contents of a
string being passed to execve(), instead we create a white-list of strings that can be
passed to it, and only allow calls to execve that are passed pointers to this syscall.
This isn&#39;t perfectly secure since someone could overwrite the contents at a later point
but it&#39;s safe enough because an attacker can&#39;t view the generated BPF to extract the
addresses, and the strings themselves should be gone from memory by the time their code
runs, preventing them from recreating the original addresses. This requires ASLR in order
to be effective at preventing an attacker from derriving the address of the strings from
previous runs.</p></li>
</ul>
<p>There&#39;s also some other profiles like ruby_timer_thread specifically for allowing node.js
to do similar things to ruby (create a thread, use epoll, etc.).</p>
<p>=== Handling flags to syscalls</p>
<p>The way the rules are defined allow syscalls like open() to not need special handling.
Since many syscalls can take flags, it&#39;s useful to be able to limit the flags they can
take.</p>
<p>{syscall =&gt; &#39;openat&#39;, permute_rules =&gt; [[&#39;2&#39;, &#39;==&#39;, \&#39;open_modes&#39;]]},</p>
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
automatically generated rules from a permutation. In this cases it&#39;s called &#39;open_modes&#39;.
A profile can add (but not remove) values to the permutation rules, and then when the
whole BPF program gets compiled it&#39;ll generate all the applicable rules for you. This
makes setting up calls like open much much simpler since you don&#39;t have to write out all
possible modes yourself. This is also an area where I could be doing better to optimize
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
operations that could make this more effective but they were not well exposed through
Linux::Seccomp when this was originally designed.</p>
<p>In the second part of this blog I&#39;ll document the proposed configuration
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
<p>Tags:
<a href="https://perlbot.pl/blog/tag/evalserver/">evalserver</a>
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
</p>
]]></content>
<updated>2017-10-10T00:00:00Z</updated>
<category term="evalserver" />
<category term="seccomp" />
</entry>
</feed>

117
blog/tag/seccomp.rss Normal file
View file

@ -0,0 +1,117 @@
<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Perlbot.pl pastebin</title>
<link>https://perlbot.pl/blog/tag/seccomp/</link>
<atom:link href="https://perlbot.pl/blog/tag/seccomp.rss" rel="self" type="application/rss+xml" />
<description>Blog feed of Perlbot.pl pastebin</description>
<generator>Statocles 0.086</generator>
<item>
<title>Seccomp and you</title>
<link>https://perlbot.pl/blog/2017/10/10/seccomp-and-you/</link>
<guid>https://perlbot.pl/blog/2017/10/10/seccomp-and-you/</guid>
<description><![CDATA[
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
(heretofore refered to as seccomp).</p>
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
systrace—which seems to be no longer supported for Linux).
-- https://en.wikipedia.org/wiki/Seccomp
</code></pre>
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
predefined rules, organized into &#39;profiles&#39;. Each profile is intended to represent a
single kind of action that a program could do, such as open a file for reading, open a
file for writing, etc.</p>
<p>I&#39;ve created a few profiles to start with</p>
<ul>
<li><p>stdio
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
<li><p>file_open
Allows calling some file related system calls, such as: open, openat, close, select,
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it&#39;s a
tty. The flags that are allowed to go to a opening a file are defined in the &quot;open_modes&quot;
rules that will be covered later</p></li>
<li><p>file_opendir
Allows opening a directory to get a list of files, and also includes the file_open
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
or similar programs</p></li>
<li><p>file_tty
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
<li><p>file_readonly
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
similar calls</p></li>
<li><p>file_write
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
<li><p>time_calls
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
<li><p>ruby_timer_thread
This one is a special ruby specific profile. It allows ruby to create a thread that
it uses internally, and only allows that thread creation with a specific set of flags,
CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
to run. It also allows for pipe2 to be called to create communication between the two
threads.</p></li>
<li><p>perl_file_temp
This was added specifically for behavior of File::Temp, and might get folded into a
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
<li><p>exec_wrapper
This one is seriously special. It&#39;s not a predefined set of rules, but in fact
generates the rules at runtime. This is because of limitations of seccomp. Since
seccomp can&#39;t inspect inside of pointers, there&#39;s no way to verify the contents of a
string being passed to execve(), instead we create a white-list of strings that can be
passed to it, and only allow calls to execve that are passed pointers to this syscall.
This isn&#39;t perfectly secure since someone could overwrite the contents at a later point
but it&#39;s safe enough because an attacker can&#39;t view the generated BPF to extract the
addresses, and the strings themselves should be gone from memory by the time their code
runs, preventing them from recreating the original addresses. This requires ASLR in order
to be effective at preventing an attacker from derriving the address of the strings from
previous runs.</p></li>
</ul>
<p>There&#39;s also some other profiles like ruby_timer_thread specifically for allowing node.js
to do similar things to ruby (create a thread, use epoll, etc.).</p>
<p>=== Handling flags to syscalls</p>
<p>The way the rules are defined allow syscalls like open() to not need special handling.
Since many syscalls can take flags, it&#39;s useful to be able to limit the flags they can
take.</p>
<p>{syscall =&gt; &#39;openat&#39;, permute_rules =&gt; [[&#39;2&#39;, &#39;==&#39;, \&#39;open_modes&#39;]]},</p>
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
automatically generated rules from a permutation. In this cases it&#39;s called &#39;open_modes&#39;.
A profile can add (but not remove) values to the permutation rules, and then when the
whole BPF program gets compiled it&#39;ll generate all the applicable rules for you. This
makes setting up calls like open much much simpler since you don&#39;t have to write out all
possible modes yourself. This is also an area where I could be doing better to optimize
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
operations that could make this more effective but they were not well exposed through
Linux::Seccomp when this was originally designed.</p>
<p>In the second part of this blog I&#39;ll document the proposed configuration
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
<p>Tags:
<a href="https://perlbot.pl/blog/tag/evalserver/">evalserver</a>
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
</p>
]]></description>
<pubDate>
Tue, 10 Oct 2017 00:00:00 +0000
</pubDate>
</item>
</channel>
</rss>

204
blog/tag/seccomp/index.html Normal file
View file

@ -0,0 +1,204 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1" name="viewport">
<link href="/theme/css/normalize.css" rel="stylesheet">
<link href="/theme/css/skeleton.css" rel="stylesheet">
<link href="/theme/css/statocles-default.css" rel="stylesheet">
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
<title>Perlbot.pl pastebin</title>
<meta content="Statocles 0.086" name="generator">
<link href="/blog/tag/seccomp.atom" rel="alternate" type="application/atom+xml">
<link href="/blog/tag/seccomp.rss" rel="alternate" type="application/rss+xml">
</head>
<body>
<header>
<nav class="navbar">
<div class="container">
<a class="brand" href="/">Perlbot.pl pastebin</a>
<ul>
<li>
<a href="/blog">Blog</a>
</li>
</ul>
</div>
</nav>
</header>
<div class="main container">
<div class="row">
<div class="nine columns">
<main>
<article>
<header>
<h1><a href="/blog/2017/10/10/seccomp-and-you/">Seccomp and you</a></h1>
<aside>
<time datetime="2017-10-10">
Posted on 2017-10-10
</time>
</aside>
<p class="tags">Tags:
<a href="/blog/tag/evalserver/" rel="tag">evalserver</a>
<a href="/blog/tag/seccomp/" rel="tag">seccomp</a>
</p>
</header>
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
(heretofore refered to as seccomp).</p>
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
systrace—which seems to be no longer supported for Linux).
-- https://en.wikipedia.org/wiki/Seccomp
</code></pre>
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
predefined rules, organized into &#39;profiles&#39;. Each profile is intended to represent a
single kind of action that a program could do, such as open a file for reading, open a
file for writing, etc.</p>
<p>I&#39;ve created a few profiles to start with</p>
<ul>
<li><p>stdio
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
<li><p>file_open
Allows calling some file related system calls, such as: open, openat, close, select,
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it&#39;s a
tty. The flags that are allowed to go to a opening a file are defined in the &quot;open_modes&quot;
rules that will be covered later</p></li>
<li><p>file_opendir
Allows opening a directory to get a list of files, and also includes the file_open
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
or similar programs</p></li>
<li><p>file_tty
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
<li><p>file_readonly
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
similar calls</p></li>
<li><p>file_write
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
<li><p>time_calls
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
<li><p>ruby_timer_thread
This one is a special ruby specific profile. It allows ruby to create a thread that
it uses internally, and only allows that thread creation with a specific set of flags,
CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
to run. It also allows for pipe2 to be called to create communication between the two
threads.</p></li>
<li><p>perl_file_temp
This was added specifically for behavior of File::Temp, and might get folded into a
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
<li><p>exec_wrapper
This one is seriously special. It&#39;s not a predefined set of rules, but in fact
generates the rules at runtime. This is because of limitations of seccomp. Since
seccomp can&#39;t inspect inside of pointers, there&#39;s no way to verify the contents of a
string being passed to execve(), instead we create a white-list of strings that can be
passed to it, and only allow calls to execve that are passed pointers to this syscall.
This isn&#39;t perfectly secure since someone could overwrite the contents at a later point
but it&#39;s safe enough because an attacker can&#39;t view the generated BPF to extract the
addresses, and the strings themselves should be gone from memory by the time their code
runs, preventing them from recreating the original addresses. This requires ASLR in order
to be effective at preventing an attacker from derriving the address of the strings from
previous runs.</p></li>
</ul>
<p>There&#39;s also some other profiles like ruby_timer_thread specifically for allowing node.js
to do similar things to ruby (create a thread, use epoll, etc.).</p>
<p>=== Handling flags to syscalls</p>
<p>The way the rules are defined allow syscalls like open() to not need special handling.
Since many syscalls can take flags, it&#39;s useful to be able to limit the flags they can
take.</p>
<p>{syscall =&gt; &#39;openat&#39;, permute_rules =&gt; [[&#39;2&#39;, &#39;==&#39;, \&#39;open_modes&#39;]]},</p>
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
automatically generated rules from a permutation. In this cases it&#39;s called &#39;open_modes&#39;.
A profile can add (but not remove) values to the permutation rules, and then when the
whole BPF program gets compiled it&#39;ll generate all the applicable rules for you. This
makes setting up calls like open much much simpler since you don&#39;t have to write out all
possible modes yourself. This is also an area where I could be doing better to optimize
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
operations that could make this more effective but they were not well exposed through
Linux::Seccomp when this was originally designed.</p>
<p>In the second part of this blog I&#39;ll document the proposed configuration
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
</article>
<ul class="pager">
<li class="prev">
<button disabled>
← Older
</button>
</li>
<li class="next">
<button disabled>
Newer →
</button>
</li>
</ul>
</main>
</div>
<div class="three columns sidebar">
<nav id="tags">
<h1>Tags</h1>
<ul class="list-inline">
<li><a href="/blog/tag/evalserver/">evalserver</a></li>
<li><a href="/blog/tag/seccomp/">seccomp</a></li>
</ul>
</nav>
<h1>Feeds</h1>
<ul class="list-inline">
<li>
<a href="/blog/tag/seccomp.atom" rel="alternate" type="application/atom+xml">
Atom
</a>
</li>
<li>
<a href="/blog/tag/seccomp.rss" rel="alternate" type="application/rss+xml">
RSS
</a>
</li>
</ul>
</div>
</div>
</div>
<footer>
<div class="container tagline">
<a href="http://preaction.me/statocles">Made with Statocles</a><br>
<a href="http://www.perl.org">Powered by Perl</a>
</div>
</footer>
</body>
</html>

View file

@ -4,13 +4,13 @@
<loc>https://perlbot.pl/</loc>
<changefreq>weekly</changefreq>
<priority>0.5</priority>
<lastmod>2017-10-02</lastmod>
<lastmod>2017-10-23</lastmod>
</url>
<url>
<loc>https://perlbot.pl/blog/</loc>
<changefreq>daily</changefreq>
<priority>0.3</priority>
<lastmod>2017-10-02</lastmod>
<lastmod>2017-10-10</lastmod>
</url>
<url>
<loc>https://perlbot.pl/blog/2017/09/28/new-blog/</loc>
@ -24,11 +24,29 @@
<priority>0.5</priority>
<lastmod>2017-10-02</lastmod>
</url>
<url>
<loc>https://perlbot.pl/blog/2017/10/10/seccomp-and-you/</loc>
<changefreq>weekly</changefreq>
<priority>0.5</priority>
<lastmod>2017-10-10</lastmod>
</url>
<url>
<loc>https://perlbot.pl/blog/tag/evalserver/</loc>
<changefreq>daily</changefreq>
<priority>0.3</priority>
<lastmod>2017-10-10</lastmod>
</url>
<url>
<loc>https://perlbot.pl/blog/tag/seccomp/</loc>
<changefreq>daily</changefreq>
<priority>0.3</priority>
<lastmod>2017-10-10</lastmod>
</url>
<url>
<loc>https://perlbot.pl/page/seccomp/</loc>
<changefreq>weekly</changefreq>
<priority>0.5</priority>
<lastmod>2017-10-02</lastmod>
<lastmod>2017-10-23</lastmod>
</url>
</urlset>