all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: sbaugh@catern.com
To: guix-devel@gnu.org
Subject: Re: Providing an alternative to setuid in GuixSD
Date: Mon, 24 Oct 2016 18:01:47 -0400	[thread overview]
Message-ID: <8760ohh0dw.fsf@catern.com> (raw)
In-Reply-To: 878tteli9w.fsf@gmail.com

Chris Marusich <cmmarusich@gmail.com> writes:
> Hi,
>
> I don't think I have all the answers, but this is an interesting topic,
> so I'll chime in with what I can.  I'm sure others will have more
> thoughts to share, too.
>
> sbaugh@catern.com writes:
>
>> 1. Each binary is an attack surface which is frequently exploited by
>>    attackers for local privilege escalation. So getting rid of them
>>    would improve security.
>>
>> 2. setuid binaries make access control decisions in an environment
>>    controlled by the user running them, by looking at files at absolute
>>    paths in that environment, such as /etc/passwd. Thus, if unprivileged
>>    users had access to chroot or other filesystem namespacing
>>    functionality, those users could escalate privileges by manipulating
>>    /etc/passwd, /etc/shadow, /etc/sudoers, and then running a setuid
>>    binary. So unprivileged chroot is not possible.
>
> When you say "filesystem namespacing functionality," are you referring
> to the Linux feature known as "user namespaces"?

I was referring to things which correspond ~directly to chroot, like
mount namespaces or Plan 9 namespaces. But it's best to just consider
chroot I think.

The vulnerability is most clear when chroot is unprivileged, but it is
present in any system with setuid binaries and the ability to perform
non-trivial filesystem namespace manipulations without privileges. (In
particular, to change what the root directory points to)

Given chroot, all you need to do is:
1. Create your own filesystem tree with your own /etc/passwd and
/etc/shadow which specifies a known password for root.
2. Chroot into that filesystem tree
3. Run su and provide the known password for root; it will check the
password against the /etc/shadow that you created.
4. Escape the chroot. Once you have root in the chroot, there are many
mechanisms for doing this.  For example, create a device file
corresponding to the real root fs, mount it, and chroot again there.
5. Enjoy your new root privileges in the main filesystem namespace.

> There is an article on LWN that discusses some of the security issues
> surrounding this:
>
> Filesystem mounts in user namespaces
> https://lwn.net/Articles/652468/
>
> I admittedly don't know a lot about this feature, but it sounds like it
> is not currently designed to let a user escalate privilege in a way that
> would enable malicious modification of system files such as /etc/passwd.
> Can you clarify your second concern a little more to help me understand?

That's partially correct; user namespaces would not allow modification
of the "real" /etc/passwd, but they would allow you to create a mount
namespace where you can put whatever file you want in place of
/etc/passwd. In fact, you could get up to step 4 of the above attack.
But then you would be stuck: You are not supposed to be able to escape a
user namespace even with root, and while you are still inside a user
namespace your privileges don't mean anything.

So, user namespaces provide an alternative solution. But they also
independently expose quite a large attack surface, and I am not really
optimistic about them being accessible unprivileged in any mainstream
distro any time soon...

I am much more optimistic about the project of eliminating setuid
binaries and thereby allowing "plain old chroot" to be safely done
without privileges. This would only allow an a small subset of the
functionality of user namespaces, but it would be enough for a lot of
applications.

> It would be nice if the Guix daemon could create chroots for building
> packages even when it runs as a non-privileged user.  That is definitely
> a limitation (see the comment about "--disable-chroot" in (guix) Build
> Environment Setup).  However, I don't understand how eliminating setuid
> binaries would enable unprivileged access to root.  Can you clarify why
> the latter follows from the former?

Eliminating setuid binaries means step 3 in the above attack outline is
not possible. A distribution without setuid binaries could therefore
safely turn on unprivileged access to chroot.

>> == How to do it ==
>>
>> Most (all?) setuid binaries can be replaced with a non-setuid binary
>> which performs local IPC to a privileged daemon.
>>
>> The largest targets for elimination are sudo and su. Luckily there is
>> already a ready alternative for those commands: ssh. We can augment lsh
>> with the rich access controls of sudo, add any extra missing features,
>> and then replace sudo/su with wrappers around ssh. (A wrapper would be
>> needed just for sheer familiarity of the system to a user.) sshd runs
>> and performs access controls in a fixed environment, so this is not
>> vulnerable to the chroot attack I mentioned above.
>>
>> Once we have a solid replacement for sudo, we can take a generic
>> approach to eliminating other setuid binaries: just replace them with
>> wrappers which call 'sudo command "$@"', and make sure the
>> sudo-replacement is appropriately configured to allow running that
>> command without authentication.
>>
>> I believe we could do this with all binaries, though there may be some
>> issues I'm not yet aware of yet.
>>
>> In the longer term I'm not sure if we would want to individually
>> replace setuid binaries with IPC-performing commands. The only real
>> benefit is maybe elegance...
>
> That's an interesting idea.  Some questions come to mind:
>
> * How would we allow one user to run a program as a different user?

Well, if user A can authenticate as user B, they certainly can also run
a program as user B through normal ssh-like means. So I assume you mean
allowing user A to run a program as user B only by authenticating as
user A.  I believe that can be achieved with some ssh tricks. (I've done
just this with ssh and Kerberos principals before; I believe you could
do the same with ssh and Unix authentication but I haven't thought about
it in much detail so I'm waving my hands a bit here)

> * How would we allow a user to update their own entries in shared
> databases like /etc/passwd?

Through IPC to a privileged process: The "passwd" tool, as an example,
could simply send a message providing the new password to a daemon
privileged to perform the actual update.

Alternatively for case of passwd specifically, we could use the tcb
framework of Openwall: http://www.openwall.com/tcb/ Which is a somewhat
more elegant trick, but may be more work and less compatible. (I'm also
not sure that it works with absolutely all PAM modules; there could be
some besides the basic files authentication which anticipate running as
root. But I don't know for sure.)

> * Could this approach work with any kernel, not just Linux?

Definitely. As described currently it's totally kernel-independent.

At some point, file-descriptor-passing-over-Unix-sockets might be
useful. That would add a very small amount of kernel-dependence as that
is sometimes available in different ways on different Unix kernels. (But
it is still generally available.)

> * Because the daemon must have enough privileges to take any potential
> action that might be requested, does this solution fail to enforce the
> principle of least privilege in basically the same way that many setuid
> programs do (because they start with more privileges than they need)?

Yes. However, it's a big advance over setuid, because the daemon runs in
a fixed environment, rather than running in an environment entirely
controlled by an unprivileged user. And that is enough of an improvement
to get big benefits, namely, safe unprivileged chroot.

> * Do you know of any prior art in this area which is similar to what you
> are proposing?  I saw some interesting-looking references in the Protego
> paper linked above, but I didn't go down the rabbit hole.

Yes, there is some pre-existing software which is directly relevant:
- s6-sudod, which is explicitly for this purpose:
http://skarnet.org/software/s6/s6-sudod.html
- remctl, which is much older but could be usable for this purpose:
https://www.eyrie.org/~eagle/software/remctl/
- systemd's machinectl has a "shell" subcommand for getting a shell in
containers running on the local host, or on the local host itself:
https://www.freedesktop.org/software/systemd/man/machinectl.html

I don't know of any Unix/Linux distributions that really use this
approach. There's some similarity to Plan 9; Plan 9 has unprivileged
namespacing in part because it doesn't have setuid.

Of course, Guix is also an example of this IPC-to-privileged-action
approach: To perform the privileged action of isolating our builds, we
perform IPC to another more privileged process which does it for us.

  reply	other threads:[~2016-10-24 22:02 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-10-23 15:17 Providing an alternative to setuid in GuixSD sbaugh
2016-10-24  0:09 ` Chris Marusich
2016-10-24 22:01   ` sbaugh [this message]
2016-10-26 12:24 ` Ludovic Courtès
2016-10-26 14:40   ` sbaugh
2016-10-28 13:34     ` Ludovic Courtès
2016-10-29 21:41       ` sbaugh
2016-10-26 17:52   ` Christopher Allan Webber
2016-10-26 18:34     ` sbaugh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8760ohh0dw.fsf@catern.com \
    --to=sbaugh@catern.com \
    --cc=guix-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/guix.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.