<div dir="ltr">FWIW, Andy and I are mainly interested in extending toybox for use as a tool for debugging Sandstorm.io apps. Sandstorm does not use selinux. In fact, Sandstorm is fundamentally opposed to selinux. :)<div><br></div><div>setpriv does many other useful things, like setting the uid/gid and enabling no_new_privs, which we do want.</div><div><br></div><div>On the topic of exec: we are interested in toybox specifically because it has the ability to run builtin commands without re-execing itself. This makes it useful for poking around inside a namespace where the toybox binary isn't actually visible in the filesystem (and /proc isn't mounted). So we would actually want to disable the recursion counter.</div><div><br></div><div>(Maybe some sort of tail recursion optimization makes sense here?)</div><div><br></div><div>-Kenton</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Oct 25, 2014 at 9:48 PM, Rob Landley <span dir="ltr"><<a href="mailto:rob@landley.net" target="_blank">rob@landley.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 10/25/14 11:00, Andy Lutomirski wrote:<br>
> On Oct 24, 2014 6:14 PM, "Rob Landley" <<a href="mailto:rob@landley.net">rob@landley.net</a>> wrote:<br>
</span><span class="">>>>> I believe you already submitted nsenter (which I merged but got<br>
>>>> distracted halfway through cleaning up. I can probably finish cleanup<br>
>>>> this weekend). I don't remember setpriv, but it sounds like fun. (What<br>
>>>> does it do?)<br>
>>><br>
>>> setpriv is a low-level tool to read and change various Linux security<br>
>>> things.  It can set real/effective uid/gid, auxiliary groups,<br>
>>> inheritable caps, cap bounding set, securebits, selinux context,<br>
>>> apparmor context, and no_new_privs.<br>
>><br>
>> I haven't done selinux or apparmor stuff in ls and cp and such. Adding<br>
>> it seems like a fairly extensive thing. (Not impossible: a compile time<br>
>> probe for "build environment has selinux support" and then a<br>
>> TOYBOX_SELINUX config thing, plus adding it to the various commands that<br>
>> would need it.)<br>
><br>
> True.  Setpriv takes the minimal approach: no libraries or<br>
> translation, just raw settings.  I only did it because I wanted to try<br>
> to cover as many relevant security settings as I could.<br>
<br>
</span>The security settings are stored in extended attributes, right?<br>
<br>
Sigh. I suppose making cp/mv support extended attributes would also help<br>
with kvm's virtfs (which uses them on the host)...<br>
<br>
Do I actually have to care about selinux itself, or will copying the<br>
extended attributes do it? No, if selinux is enabled on the host it'll<br>
force you to access the extended attributes _through_ the security<br>
infrastructure, won't it?<br>
<br>
(I very, very vaguely remember reading this code when I maintained<br>
busybox. Eight years ago.)<br>
<span class=""><br>
>> That said, I'm not really a fan of selinux: the NSA designed a system so<br>
>> complicated that you have to take the authors' word that this 50,000<br>
>> rule stack is actually doing soemthing useful. Post-Snowden, we actually<br>
>> _know_ they had projects to undermine cryptographic protocols and<br>
>> introduce backdoors to let them into systems and so on. But people still<br>
>> trust selinux. I don't understand why.<br>
>><br>
>> Is there a consensus on whether or not we should go there?<br>
><br>
> Wait until there's actual demand?<br>
<br>
</span>I'm pretty happy with that. That said, setpriv has this feature. Is<br>
setpriv useful _without_ this feature?<br>
<span class=""><br>
>> Something like 95% of the overhead of fork/exec is the exec part. Fork<br>
>> is cheap... when you have an mmu. :)<br>
><br>
> I suppose that toysh could do it zygote style: fork once at or soon<br>
> after startup, and then, as needed, fork new processes off the clean<br>
> forked child.<br>
<br>
</span>That's more or less the general idea of any shell: toysh keeps itself<br>
clean, calls fork, and has the child processes do the strange bits. You<br>
don't have a dedicated zygote, the parent process _is_ the zygote.<br>
<br>
There are various cases like the umask builtin and exec redirects where<br>
you modify the state of the current shell and it is inherited by the<br>
child processes. You _need_ to have these changes inherited by children,<br>
so you'd have to impose them upon a "zygote" cross-process, which isn't fun.<br>
<br>
(Heck, exported environment variables are inherited by child processes,<br>
the "VAR=VALUE commandname" stuff just does the fork first and does the<br>
exports in the child so the parent shell's environment is affected. You<br>
can do all sorts of stuff in the child (after the fork) before launching<br>
the command, and it goes away when the child does. The problem with this<br>
is vfork() on nommu systems, but a "zygote" doesn't really help there.)<br>
<br>
A shell has to be implemented as a long-running program just like a<br>
webserver. It's designed around keeping track of its state and not<br>
leaking resources, but its state isn't entirely static either.<br>
<span class="HOEnZb"><font color="#888888"><br>
Rob<br>
</font></span></blockquote></div><br></div>