Using CHILD_SUBREAPER in GNU Shepherd

2017-06-03 Thread sbaugh

Hi,

There is a feature present in Linux: CHILD_SUBREAPER.

It changes the logic for reparenting orphaned processes. Instead of an
orphaned process being reparented to pid1, an orphaned process is
reparented to the nearest parent that is marked as a CHILD_SUBREAPER.
A process can mark itself as a CHILD_SUBREAPER without privileges.

See PR_SET_CHILD_SUBREAPER in prctl(2) for maybe more precise
information: http://man7.org/linux/man-pages/man2/prctl.2.html

What this boils down to is allowing process supervisors to be much more
reliable, even when not running as init, because they can track not just
their children, but their children's children, and in general all
transitive children. I'd like to add it to GNU Shepherd.

It may require some re-architecting to take full advantage of it. I'm
not sure yet.  I wrote a small tool using CHILD_SUBREAPER to provide
some useful process supervision features:
https://github.com/catern/supervise

The relevant features are:
- Guaranteed cleanup of all started processes
- Usable in nested situations
I'd like to get such features into GNU Shepherd. (maybe the latter is
already possible, but explicit support can't hurt)

Does this sound like a good idea?

There aren't many process supervisors out there which actually use
CHILD_SUBREAPER, which I find rather disappointing, because it allows
container-like cleanup without actually having root privileges.

In the longer term, if we had this feature in the shepherd, we could
make some container-like guarantees about starting up daemons and
applications out of Guix on foreign distros: Not only will the
dependencies be pulled from the store, but also absolutely no processes
can be remaining on the system after the daemon is terminated, if it is
started with the shepherd. That would a really unique guarantee!

It could also help with store garbage collection, perhaps?

Thanks for Guix!




Re: Providing an alternative to setuid in GuixSD

2016-10-29 Thread sbaugh
l...@gnu.org (Ludovic Courtès) writes:
> I think we must just be clear that GuixSD will be the only one to
> benefit from a solution along the lines you wrote, at least for the
> foreseeable future.

Well, I am slightly more optimistic than that. It may be that this
solution is such a success that other distros emulate us. :) But, yes,
there is no clear path for this work to be used by anything but GuixSD
(and NixOS). I think that is fine; we should not fear to innovate.

> It seems to me that your proposal could be summarized as (1) replacing
> sudo with a sudo-that-uses-IPCs (fine), and (2) replacing other setuid
> programs by a wrapper that does “sudo program”.

Yes.

> Item #2 is already possible, but it doesn’t look “better” to me that
> setuid programs from a security or configuration viewpoint.

Right, item #2 is only useful when it allows actually getting to the
0-setuid-binaries state; that is, item #2 requires that item #1 has
already been achieved to be useful.

> Namespaces look like an improvement to me.  If you want something less
> hacky, there’s always the Hurd.  ;-)

They're definitely an improvement. Don't get me wrong, I am absolutely
excited about user namespaces.

But they have a lot of drawbacks. They expose a huge amount of
formerly-privileged APIs to unprivileged processes, causing security
problems. They require system-wide configuration and allocation of uids
for the UID mapping. Working across multiple namespaces isn't possible
and if it ever is possible it will probably require making the whole
thing even more complicated. And finally it's just rather weird to have
to create a different user namespace, gain pseudo-root, and execute
syscalls using fake capabilities just to manipulate your view of the
filesystem. Indeed I prefer the Hurd here. :)

If we get rid of setuid binaries in userspace, these kernel APIs can be
redesigned in a simpler and more powerful way. To improve the GNU/Linux
system we can't just rely on kernel development: We must also develop
userspace to open up paths forward.

>> I mean new kernel features - I'm skeptical that user namespaces provide
>> an intuitive or easy to use API, and I have some ideas on what would be
>> better. But the features I want to develop rely on getting rid of
>> setuid, so I'm starting there. :)
> What features do you have in mind?

I don't want to prescribe any specific set of features.  Unprivileged
chroot or equivalent, without having to first go through user
namespaces, would be a start. In combination with unprivilegd bind
mounts it would give us quite a lot of what we need.

If I had to be specific about features, I would say that it would be
nice to port an API like Plan 9 namespaces to Linux. (Hurd-like features
would also be acceptable.) Perhaps this is overly optimistic.

> Polkit has its own sudo-like program, ‘pkexec’, that works by talking to
> the polkit daemon over D-Bus.

I've investigated this. pkexec requires being setuid: it only does
authentication with polkit; it actually runs things just like sudo, by
setreuid and exec, rather than telling a daemon to run it.




Re: Providing an alternative to setuid in GuixSD

2016-10-26 Thread sbaugh
Christopher Allan Webber  writes:
> So, you're running psudo, and this thing maybe accepts connections over
> something more secure, *maybe* unix domain sockets... so restrict group
> access to the socket to users in the "psudo" group.
>
> From there, maybe it could require PAM authentication while entering the
> root password, or something.
>
> It feels hard to know how psudo could "know" what user is accessing the
> socket... I don't think that information is made available, right?
> Maybe I'm wrong!  I guess postgres and etc do similar things?

On Linux, there is SCM_CREDENTIALS (and similar stuff on BSDs). From
Linux unix(7):

SCM_CREDENTIALS
Send or receive UNIX credentials.  This can be used for authentication.
The credentials are passed as a struct ucred ancillary message.  Thus
structure is defined in  as follows:

   struct ucred {
   pid_t pid;/* process ID of the sending process */
   uid_t uid;/* user ID of the sending process */
   gid_t gid;/* group ID of the sending process */
   };

Moreover there is the Polkit (ne PolicyKit) framework for this kind of
stuff, which could provide a more high-level interface if we chose to
use it. (GNOME uses it as does systemd)

(Note that there is already pkexec (bundled with Polkit) which provides
a sudo replacement with authentiation and policy through Polkit. But
it's setuid for some reason. I haven't investigated why...)




Re: Providing an alternative to setuid in GuixSD

2016-10-26 Thread sbaugh
l...@gnu.org (Ludovic Courtès) writes:
> Well, the kernel Linux will forever support setuid binaries

That can be selectively turned off per-mount, simply specify the nosuid
option. And so eventually we can get to a point where setuid is a Linux
build configuration option, which distros can turn off.

> and thus, most likely, chroot(2) will forever be restricted to root.

This too can be a configuration option. And it's entirely possible for
distros to turn it on after setuid is turned off.

These decisions about setuid and chroot are distribution decisions;
distributions can and should make decisions and innovate independent of
the Linux kernel's default configuration. (That's part of how the whole
GNU/Linux ecosystem works)

On another point, even if chroot is forever privileged, new syscalls can
be developed which duplicate the functionality of chroot with more
flexibility and less baggage. But they will certainly face the same
issue as chroot if they wish to be made unprivileged. Mount namespaces,
for example, (with a bit of tweaking of the API to make it actually
useful unprivileged) could be made unprivileged without relying on user
namespaces, but face the same problems as chroot. So by removing setuid
we are laying the groundwork for innovation not just by allowing
unprivileged chroot.

>> I think also the ability to build a setuid-free system could make GuixSD
>> a useful platform for innovation in the use of filesystem namespaces. (I
>> myself certainly have plans in this area.)
>
> Our ‘linux-libre’ package has support for user namespaces and other
> namespaces built in already (this is the default kernel config I think),
> so one can already play with namespaces on GuixSD and on other distros
> that enable it.  :-)

I mean new kernel features - I'm skeptical that user namespaces provide
an intuitive or easy to use API, and I have some ideas on what would be
better. But the features I want to develop rely on getting rid of
setuid, so I'm starting there. :)

>> The largest targets for elimination are sudo and su. Luckily there is
>> already a ready alternative for those commands: ssh. We can augment lsh
>
> SSH is a complex protocol and its implementations are complex too.  I
> would find it unreasonable to replace ‘su’ and ‘sudo’ with something
> this complex, that goes through the TCP/IP stack, etc.

Yes, that is true. The sole virtue of ssh here is that it already exists
and is used for this purpose.

What if we adapted s6-sudod, or wrote something from scratch? Or perhaps
patched sudo to work in some way over IPC? I think a generic solution is
useful. Maybe something should be written specifically for GuixSD,
configured with Guile? Or maybe something which makes use of the putative
standard, PolicyKit, which is configured with Javascript?




Re: Providing an alternative to setuid in GuixSD

2016-10-24 Thread sbaugh
Chris Marusich  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.
>
> sba...@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 

Providing an alternative to setuid in GuixSD

2016-10-23 Thread sbaugh

Hi guix-devel,

Has any effort been put into eliminating the need for setuid binaries
from GuixSD? I would be interested in working on that.

== Why remove setuid binaries? ==

setuid binaries are problematic for two reasons:

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.

Issue 2 is a matter near and dear to our hearts here in guix-land, and
is my primary motivation. My understanding is that if we eliminated
all setuid binaries, we could with some confidence begin to allow
unprivileged access to chroot/filesystem namespaces, without first
going through user namespaces (which have their own issues). Please
correct me if you believe this is wrong.

Unprivileged access to chroot would of course greatly aid unprivileged
installation of guix. So I think it only right that we should take the
necessary steps to support it in GuixSD. Then maybe (in a decade or
so...) it'll be picked up by Debian and other large distributions.

I think also the ability to build a setuid-free system could make GuixSD
a useful platform for innovation in the use of filesystem namespaces. (I
myself certainly have plans in this area.)

== 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...

Does this plan makes sense in the context of GuixSD? Am I leaving out
anything?
Thanks!




Re: Developing libraries for the GNU system with Guix

2016-10-14 Thread sbaugh
l...@gnu.org (Ludovic Courtès) writes:
> sba...@catern.com skribis:
>> - Currently every dependency is located at a well known globally unique
>>   and globally meaningful path; add some kind of "variant package"
>>   construct which specifies a package which is "passed in" to the
>>   environment (maybe by bind-mounting it in a filesystem namespace;
>>   implementation specifics aren't important). To put this in a
>>   programming language sense, one of these packages being present would
>>   turn a Guix distribution from a value into a function.
>
> Not sure I understand.  What do you mean by “passed in to the
> environment”?

I just mean that this would be a path that is not necessarily pointing
to a directory containing the files desired by other packages depending
on it. To make a complete functioning system, the path would need to be
pointed at something containing the right files. (something of the right
type) It could be pointed at different directories in different
filesystem namespaces, and that "pointing" would happen outside the
filesystem namespace when the namespace is created.




Developing libraries for the GNU system with Guix

2016-10-13 Thread sbaugh

Hi guix-devel,

When I am hacking on some library Z, I continuously want to test the
effects that my changes to Z have on packages A/B/C which depend on
Z. The same applies, in general, when hacking on any package Z which
other packages A/B/C depend on: While developing, I want to be able to
rapidly mutate Z and see how this affects A/B/C.

I am not sure how to best achieve this. Here are some solutions:

- When you change Z, rebuild A/B/C.
  This is much too slow at present.

- Use grafts to update A/B/C through binary patching.
  This is also too slow, and AFAIK it can't really be sped up.

- Use LD_LIBRARY_PATH to cause A/B/C to search for Z in a mutable place.
  This works for C libraries, but not generically; there are equivalent
  variables for some other languages but it's not a full solution.

- Before starting to hack on Z, build a new version of Z which includes
  a random hash and which A/B/C depend on; then bind-mount a mutable
  directory on top of that. (suggested by mark_weaver on IRC)
  This is the most palatable hack, but still a hack. The inclusion of a
  random hash prevents collision with other packages and the use of
  bind-mounting means we aren't actually mutating the store. This
  unfortunately also requires privileges: it's not usable by
  unprivileged users.

Here are some not currently available possibilities:

- Create some kind of GUIX_LIBRARY_PATH in which packages are looked up
  first before looking at the compiled-in hash.
  This would be an attempt to make a generic equivalent of
  LD_LIBRARY_PATH. This could theoretically be implemented with variant
  symlinks, if they were available: https://lwn.net/Articles/680705/

- Currently every dependency is located at a well known globally unique
  and globally meaningful path; add some kind of "variant package"
  construct which specifies a package which is "passed in" to the
  environment (maybe by bind-mounting it in a filesystem namespace;
  implementation specifics aren't important). To put this in a
  programming language sense, one of these packages being present would
  turn a Guix distribution from a value into a function.

- Massively speed up rebuilding A/B/C by performing incremental
  builds. Not sure how exactly this could work, it's just a thought.

What do you think, guix-devel?

By the way, I think this is a pretty important feature overall (though
it's described in fairly abstract terms in this email). I think this is
one of the last missing features to make the Guix approach a clear and
uncontroversial improvement over existing widespread practices.




Re: GUIX_LOCPATH in daemon unit file

2016-07-17 Thread sbaugh
I think including glibc-utf8-locales in the binary tarball is a good
idea, it eases usability and doesn't really have any downsides. (if a
really minimal tarball is needed for some purpose, that can be built
separately)




Foreign distro GUIX_LOCPATH errors when installing from manual

2016-07-05 Thread sbaugh

Hi,

I was just getting started with Guix by installing it on my regular
distro, Debian Jessie, by following the manual (which is really great -
I tried installing Nix first but couldn't get it to work, the Guix
manual is much better).

The install was successful but I noticed two errors related to
GUIX_LOCPATH which I had to fix by asking others for advice. Both happen
when running guix package commands as a regular user, by running
/usr/local/bin/guix.

- substitute: warning: failed to install locale: Invalid argument

This was a result of the daemon, running as root, not having
GUIX_LOCPATH set in its environment.

My solution was installing glibc-locale in root's profile, and adding:

Environment=GUIX_LOCPATH=/root/.guix_profile/lib/locale

to the [Service] section of the systemd unit file used to start the
daemon. I suggest that this line should be added to the unit file
shipped with guix, and that the installation instructions say to install
glibc-locale (or some other locale package) in root's profile.

- warning: failed to install locale: Invalid argument

This was a result of the user running guix not having GUIX_LOCPATH set
in their current environment. But, keep in mind, the user is running
guix through /usr/local/bin/guix, which is in fact a symlink to root's
guix.

I suggest that the appropriate solution is to instead of symlinking
/usr/local/bin/guix to
/var/guix/profiles/per-user/root/guix-profile/bin/guix, we should
replace /usr/local/bin/guix with the following shell script:

#!/bin/sh
export GUIX_LOCPATH=/var/guix/profiles/per-user/root/guix-profile/lib/locale
/var/guix/profiles/per-user/root/guix-profile/bin/guix $*

That is, root's guix should be run with root's locales.


Hopefully these can be fixed!