<?xml version="1.0" encoding="utf-8"?> 
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <generator uri="https://gohugo.io/" version="0.78.2">Hugo</generator><title type="html"><![CDATA[sandbox on Roy's Blog]]></title>
    
        <subtitle type="html"><![CDATA[Mainly about tech stuff I have a hand in]]></subtitle>
    
    
    
            <link href="https://roy.marples.name/blog/tags/sandbox/" rel="alternate" type="text/html" title="HTML" />
            <link href="https://roy.marples.name/blog/tags/sandbox/atom.xml" rel="self" type="application/atom+xml" title="Atom" />
            <link href="https://roy.marples.name/blog/tags/sandbox/feed.json" rel="alternate" type="application/json" title="Json" />
    <updated>2021-03-12T11:08:32+00:00</updated>
    
    <id>https://roy.marples.name/blog/tags/sandbox/</id>
        
        <entry>
            <title type="html"><![CDATA[Capsicum vs Pledge Final Thoughts]]></title>
            <link href="https://roy.marples.name/blog/posts/capsicum_vs_pledge_final_thoughts/?utm_source=atom_feed" rel="alternate" type="text/html"  hreflang="en" />
            <id>https://roy.marples.name/blog/posts/capsicum_vs_pledge_final_thoughts/</id>
            
            <published>2020-06-15T17:15:00+00:00</published>
            <updated>2020-06-15T17:15:00+00:00</updated>
            
            
            <content type="html"><![CDATA[<p>Following on from <a href="../capsicum_vs_pledge_part2">Capsicum vs Pledge Part 2</a>
I thought I would post my final thougts on the topic as the development
on these sandbox technologies draws to a close in <a href="/projects/dhcpcd">dhcpcd</a>.</p>
<p>But first, let us discuss &hellip;</p>
<h2 id="the-posix-resource-limited-sandbox">The POSIX Resource Limited sandbox</h2>
<p>POSIX documents
<a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/getrlimit.html">setrlimit(2)</a>.
Disabling the ability to open new files, sockets, etc, or create new processes
is actually pretty powerful.</p>
<p>Thanks to the privsep dhcpcd now has to support both Capsicum and Pledge, this
turned out to be pretty easy to implement.
The <em>only</em> issue with this is the
<a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html">poll(2)</a>
interface which dhcpcd makes great use of.
Implementations found on Linux, OpenBSD and Solaris return <code>EINVAL</code> when the
<code>nfds</code> argument is greater than <code>RLIMIT_NOFILE</code> where-as the other OS&rsquo;s dhcpcd
supports don&rsquo;t.
This means that on Linux, OpenBSD and Solaris an attacker could close
an exiting file descriptor and try to open a new one.
On OpenBSD this is not that much of a big deal because pledge should stop
that from happening.
On Linux and Solaris, they can&rsquo;t open a file thanks to the chrooted empty
directory but they can create a new one.
But thanks to <code>RLIMIT_FSIZE</code> they can&rsquo;t actually write to it.
At most they could create a network socket and send arbitary data over it.
For Linux, we could look into using seccomp to stop this.</p>
<p>For implementations such as NetBSD and FreeBSD, setting <code>RLIMIT_NOFILE</code> to zero
with poll(2) still working means they cannot create any few file descriptor.
This means that if an attacker breaches a resource limited process it
<strong>can only work with the resources it has</strong> because it cannot fork another
process, nor open any files, sockets, etc.
It&rsquo;s also running as an unpriviledged user locked in an empty directory,
so there is nothing to see or do there.
All the resources it currently has are:</p>
<ul>
<li>PF_INET, PF_LINK, etc sockets that can only query for data</li>
<li>network proxy process (receives only, does not send)</li>
<li>BPF processes (send and receive, the read and write filters are also locked)</li>
<li>privileged actioneer (filters ioctls, validates paths and outbound traffic)</li>
</ul>
<p>So the only way to do anything outside of what dhcpcd normally does is to use
a facility that does not need to create a file or socket, or fork a process.
The only remaining avenue of attack is to break the privileged actioneer
process- that cannot be protected by any sandboxing as it needs to do a lot
of stuff. Both OpenBSD&rsquo;s and FreeBSD&rsquo;s dhclient have such a privileged
process as well.</p>
<p>The priviledged actioneer process itself doesn&rsquo;t do a great deal.
For example to add a route on BSD you create a RTM_ADD message.
The master process will do this and instead of writing to the PF_ROUTE socket
itself it will pass the message to the privilged actioneer process which
in turn writes to it&rsquo;s PF_ROUTE socket.
Every ioctl, path accessed or network bound packet is validated by the
privileged actioneer. Even though it&rsquo;s generic, it&rsquo;s also locked down.</p>
<h2 id="so-what-extra-to-capsicum-and-pledge-bring-to-the-table">So what extra to Capsicum and Pledge bring to the table?</h2>
<p>Both bring system call filtering.
For example,
<a href="https://netbsd.gw.com/cgi-bin/man-cgi?sysctl+3+NetBSD-current">sysctl(2)</a>
does not need to create a new resource.
Information available to the ordinal user such as
<a href="https://en.wikipedia.org/wiki/Uname">uname</a> may not be
desirable to leak to these sandboxed processes.
But then the question to ask is what can they do with it?</p>
<p>Pledge overcomes the <code>RLIMIT_NOFILE</code> limitation for poll(2) on OpenBSD.</p>
<p>Capsicum goes a bit futher by limiting rights of each resource you
have in terms of what you can do with them.</p>
<p>What they both bring to the table though is making sandboxing easier.
Here, Pledge is the outright winner. As I pointed out in my initial blog
post, Pledge is really easy.
But make it too easy and it&rsquo;s not as secure as it could be.
Capsicum is harder and the resource limited sandbox is harder still.</p>
<p>The take-away point from this is while Capsicum and Pledge are nice,
they don&rsquo;t beat a good design.</p>
]]></content>
            
                 
                    
                         
                        
                            
                             
                                <category scheme="https://roy.marples.name/blog/tags/tech" term="tech" label="tech" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/code" term="code" label="code" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/dhcpcd" term="dhcpcd" label="dhcpcd" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/sandbox" term="sandbox" label="sandbox" />
                            
                        
                    
                
            
        </entry>
    
        
        <entry>
            <title type="html"><![CDATA[Capsicum vs Pledge in a Network Management Tool ... Part 2]]></title>
            <link href="https://roy.marples.name/blog/posts/capsicum_vs_pledge_part2/?utm_source=atom_feed" rel="alternate" type="text/html"  hreflang="en" />
            <id>https://roy.marples.name/blog/posts/capsicum_vs_pledge_part2/</id>
            
            <published>2020-05-14T14:00:00+00:00</published>
            <updated>2020-05-14T14:00:00+00:00</updated>
            
            
            <content type="html"><![CDATA[<p>A few days ago I posted about <a href="../capsicum_vs_pledge">Capsicum vs Pledge</a>
in dhcpcd. Well, I finished the Capsicum integration yesterday so I thought
I would take some time to revisit my findings.</p>
<h2 id="capsicum-is-hard-to-develop-for">Capsicum is hard to develop for</h2>
<p>It&rsquo;s either on or off.
You can limit each FD with capabilites mode off, but I&rsquo;m not sure what that gains
as it&rsquo;s mainly there to allow the FD to be used in the restricted world so
we can treat it as either on or off really.</p>
<p>Pledge is granular, you can turn areas on or off.
For example, you can allow full file access while restricting various ioctls.
Ideally, the only thing you want to pledge is stdio, which is kinda needed
for the Privilege Separation IPC to work.
However, we end up pledging dns inet and route as well.</p>
<p>So why is Capsicum harder? Well, the short answer is that it&rsquo;s not.
The long answer is that it&rsquo;s perceived to be harder because you have to
do all the work up front to get your code working whereas Pledge allows you
do it it piece meal.</p>
<h2 id="pledge-is-as-secure-as-capsicum">Pledge is as secure as Capsicum</h2>
<p>As I said in my prior post, I&rsquo;m not a security expert, but here&rsquo;s my findings:</p>
<p>You can make Pledge as secure as Capsicum, <strong>but you don&rsquo;t have to</strong>.</p>
<p>As a user on OpenBSD I can see lots of processes marked with <code>p</code> to indicate
they have pledged something.
<del>What that something is though is a black box.</del>
You can use <code>ps-o pledge-p $pid</code> to show the promises a process has pledged.
The more promises you see the more that process is allowed to do.
Short list good, long list bad.</p>
<p>As a user on FreeBSD I can see lots of processes marked with &lsquo;C&rsquo; to indicate
they are in Capsicum Capabilites Mode. Because this is just on or off, I
know exactly what this process can and cannot do.</p>
<p>Armed with this knowledge I would trust a Capsicum enabled application more
than a Pledge enabled application. But to fully trust either you still need
to audit the code.</p>
<h2 id="they-both-have-limitations">They both have limitations</h2>
<p>With a Pledged process you cannot change a BPF filter with the bpf pledge.
This is unfortunate, a possible solution could be to spawn a process AND filter
for every address you want to monitor for DaD or ARP pinging.
That <em>could</em> be a lot of resources wasted as BPF is neither infinite nor cheap.</p>
<p>With a Capsicum Capability Mode enabled process you cannot call sendto(2)
that is not connected.
Unlike the above, there is no easy solution.
I can&rsquo;t spawn off another process because unlike normal communication,
because I <strong>need</strong> to bind to the <code>bootpc</code> and <code>dhcpv6-client</code> ports
so I can dictate which source port is used to send the message.
The binding would then fail because the network proxy process
is already using the port.
A possible solution is to call RTM_GET to work out which host I send to
on the local network, craft the packet by hand and send it out using a BPF
socket.</p>
<p>I strongly feel that both should be fixed upstream:</p>
<ul>
<li>the bpf Pledge should allow changing the BPF filter.</li>
<li>Capsicum should allow sendto unconnected if bound to a priviledged port or another capability created to grant to the socket.</li>
</ul>
<p>As it stands, dhcpcd does not Pledge for BPF processes and does not run
the generic network proxy process in Capsicum Capabilites mode.
However, both processes are using the unprivileged user and chrooted to an
empty directory. Neither do any processing of data coming in, they just
ferry it back to the master process via IPC which runs under the same
restrictions but is also sandboxed with Pledge or Capsicum so I&rsquo;m
confident that it&rsquo;s good enough.</p>
]]></content>
            
                 
                    
                         
                        
                            
                             
                                <category scheme="https://roy.marples.name/blog/tags/tech" term="tech" label="tech" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/code" term="code" label="code" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/dhcpcd" term="dhcpcd" label="dhcpcd" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/sandbox" term="sandbox" label="sandbox" />
                            
                        
                    
                
            
        </entry>
    
        
        <entry>
            <title type="html"><![CDATA[Capsicum vs Pledge in a Network Management Tool]]></title>
            <link href="https://roy.marples.name/blog/posts/capsicum_vs_pledge/?utm_source=atom_feed" rel="alternate" type="text/html"  hreflang="en" />
            <id>https://roy.marples.name/blog/posts/capsicum_vs_pledge/</id>
            
            <published>2020-05-12T11:46:00+00:00</published>
            <updated>2020-05-12T11:46:00+00:00</updated>
            
            
            <content type="html"><![CDATA[<p>So one of the big goals of <a href="/projects/dhcpcd">dhcpcd</a> was to implement
<a href="https://en.wikipedia.org/wiki/Privilege_separation">Privilege Separation</a>.
This was achieved in <a href="/blog/dhcpcd-9-0-0-released.html">dhcpcd-9</a> which was
important because it was a required step of work to
<a href="https://lists.freebsd.org/pipermail/freebsd-net/2019-October/054535.html">merge dhcpcd into FreeBSD base system</a>. Once done, we can then look at what is
required to enable <a href="https://wiki.freebsd.org/Capsicum">Capsicum</a> support,
which is the last required step before dhcpcd can even be considered for
importing into FreeBSD base system.</p>
<p>The good news is that <em>basic</em> Capsicum support has been enabled in
<a href="https://roy.marples.name/cgit/dhcpcd.git/commit/?id=727b7e9bf8b2fe810913c76c5fd36767869944bb">this commit</a> by ensuring all the file descriptors of the
network facing processes are limited in their capability.
The bad news is that <a href="https://www.freebsd.org/cgi/man.cgi?capsicum(4)">capability mode</a> is only enabled for the BPF processes- the end goal is that
the master process is at least placed in capability mode.</p>
<p>So what&rsquo;s the problem? Well, the first problem is that Capsicum is really
hard to use, a lot of this is not helped by the documentation.
It took a long time to work out how it works and how to use it.
The second problem is that capability mode is really hard core- it stops
a lot of stuff working dead in it&rsquo;s tracks by killing access not capability
limited in the global namespace.</p>
<p>From dhcpcds perspective the big issue is that
<del>gethostname(3) and</del> getifaddrs(3) won&rsquo;t work.
This is the biggest show stopper, hard to IPC.</p>
<p><em>EDIT: gethostname(3) does work in Capsicum capabilities mode.</em></p>
<p>Let&rsquo;s just take a moment to talk about getifaddrs(3)- it&rsquo;s a really
powerful interface to work out what interfaces are available to work with.
In some OS it&rsquo;s the only mechanism to get the hardware address assigned
to an interface. Also, it&rsquo;s possible for the route(4) (or netlink(7))
socket to overflow so it&rsquo;s required to re-learn the system state which means
it cannot be cached.
Not that FreeBSD supports reporting route(4) overflow, but that&rsquo;s another story.</p>
<p>Due to the getifaddrs(3) show stopper, I decided to look into
<a href="https://man.openbsd.org/pledge.2">OpenBSDs pledge(2)</a>. While the documentation
is still very technical, it&rsquo;s easier to read and understand compared to
Capsicum. It&rsquo;s also really <em>really</em> <strong>really</strong> easy to implement in comparison
as you only pledge features rather than each file descriptor.
Because of this, it&rsquo;s also very granular.
<a href="https://roy.marples.name/cgit/dhcpcd.git/commit/?id=2f9d9eae5fb8fb1922b0e096e157987ac0df110e">The initial commit to enable pledge</a> is mainly allowing the
current ioctl IPC framework to pass data back again.</p>
<p>But can we do better? Can we operate with the same Pledges that OpenBSDs
dhclient(8) uses? The answer is of course <strong>YES</strong>!
By caching some initial data that does not change such as utsname and
machine uuid AND moving all file IO to privsep,
<a href="https://roy.marples.name/cgit/dhcpcd.git/commit/?id=2f9d9eae5fb8fb1922b0e096e157987ac0df110e">this commit</a>
allows almost perfect Pledge support.
We could go better if privsep gains support for the <code>SIOCGIFGROUP</code> ioctl as
this would allow the <code>inet</code> pledge to be dropped.
It&rsquo;s not quite perfect because
<a href="http://openbsd-archive.7691.n7.nabble.com/pledge-bpf-32bit-arch-unbreak-td299901.html">a Pledged process cannot change a BPF filter</a>.
We would need to space a BPF process per address which is then limited by the
number of BPF instances you are allowed. I&rsquo;m not sure this a good thing, and
ironically BPF processes are the one thing we have in Capsicums capability mode.
This is also a massive improvement over the initial dhcpcd-9 release because
it means we no longer need any files in the chroot directory and <code>/var/empty</code>
can be used again.
This alone should make current and new FreeBSD users of dhcpcd quite happy.
It will also go some way to enabling capabilities mode for the master
dhcpcd process in the future.</p>
<p>Now, I can&rsquo;t say which technology is more secure- that&rsquo;s really not my field
of expertise.
I can&rsquo;t even say if either are really needed or actually make security worse
because Privilege Separation
<a href="https://en.wikipedia.org/wiki/Inter-process_communication">IPC</a>
adds more code, complexity and as such could make it more prone
to bugs some of which could be a security attack vector in itself.</p>
<p>But what I can say is that Pledge is much easier to develop for
because it&rsquo;s really granular unlike Capsicum which is either on or off or
per fd limited.</p>
<p>I&rsquo;ll continue working on Capsicum support in dhcpcd just to see if I can
enable Capabilites Mode in the master process.
When that&rsquo;s finished I will do a more in-depth comparison of these two
technologies.</p>
]]></content>
            
                 
                    
                         
                        
                            
                             
                                <category scheme="https://roy.marples.name/blog/tags/tech" term="tech" label="tech" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/code" term="code" label="code" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/dhcpcd" term="dhcpcd" label="dhcpcd" />
                             
                                <category scheme="https://roy.marples.name/blog/tags/sandbox" term="sandbox" label="sandbox" />
                            
                        
                    
                
            
        </entry>
    
</feed>
