git-daemon may unexpectedly run as root

2019-07-14 Thread Stefan Sperling
Overriding gitdaemon_flags in /etc/r.conf.local will cause rc.d to
run git-daemon run as root instead of the expected _gitdaemon user.

To reproduce, try an rc.conf.local line such as:
   gitdaemon_flags=--listen=127.0.0.1 /git

This happens because the rc script currently depends on git-daemon itself
to switch the user ID, rather than using rc.d's built-in mechanism which
forces a UID with su(1). If the user overrides the flags, no UID switch
will happen.

Anyone exposing git-daemon to the public internet on an OpenBSD system
should check their system. This line in rc.conf.local will force the
daemon to run under its dedicated user account:
   gitdaemon_user=_gitdaemon

Note that git-daemon does not support any of the standard exploit
mitigation measures regular OpenBSD daemons provide; there is not
even support for chroot(8).

Fix for the port:

diff 64e903a627aaf6f20b8adcb3028f2aad79137a9e /usr/ports
blob - c5ddeb706f54602a8c1648ec1825eaf8cb1f99ba
file + devel/git/Makefile
--- devel/git/Makefile
+++ devel/git/Makefile
@@ -5,6 +5,7 @@ COMMENT-svn =   GIT - subversion interoperability tools
 COMMENT-x11 =  GIT - graphical tools
 
 V =2.22.0
+REVISION = 0
 DISTNAME = git-${V}
 PKGNAME-main = ${DISTNAME}
 PKGNAME-svn =  git-svn-${V}
blob - daf33d41548331295cd05bcb53f075781bce9b90
file + devel/git/pkg/gitdaemon.rc
--- devel/git/pkg/gitdaemon.rc
+++ devel/git/pkg/gitdaemon.rc
@@ -3,7 +3,7 @@
 # $OpenBSD: gitdaemon.rc,v 1.3 2018/01/11 19:27:02 rpe Exp $
 
 daemon="${TRUEPREFIX}/bin/git daemon --detach"
-daemon_flags="--user=_gitdaemon"
+daemon_user="_gitdaemon"
 
 . /etc/rc.d/rc.subr
 



Re: git-daemon may unexpectedly run as root

2019-07-14 Thread Klemens Nanni
On Sun, Jul 14, 2019 at 03:46:06PM +0200, Stefan Sperling wrote:
> Overriding gitdaemon_flags in /etc/r.conf.local will cause rc.d to
> run git-daemon run as root instead of the expected _gitdaemon user.
Well, you ought to check the existing daemon flags before changing them.

Admittedly, this is suboptimal and users have to carry the options along
themselves, but some third-party daemons will not work with `daemon_user`,
and I believe git-daemon(1) is one of them.

> 
> To reproduce, try an rc.conf.local line such as:
>gitdaemon_flags=--listen=127.0.0.1 /git
> 
> This happens because the rc script currently depends on git-daemon itself
> to switch the user ID, rather than using rc.d's built-in mechanism which
> forces a UID with su(1). If the user overrides the flags, no UID switch
> will happen.
Off the top of my head, I know that this is the case for security/hitch
and net/tinc as well.  I remember discussion about putting `-u $user'
into `$daemon' itself to enforce the user for cases where our rc.subr(8)
framework is not applicable, but there were objections.

> Anyone exposing git-daemon to the public internet on an OpenBSD system
> should check their system. This line in rc.conf.local will force the
> daemon to run under its dedicated user account:
>gitdaemon_user=_gitdaemon
This will also (partially?) break git-daemon(1)'s `--inetd' option,
I think.  From the manual:

--user=, --group=
Change daemon’s uid and gid before entering the service loop. When
only --user is given without --group, the primary group ID for the
user is used. The values of the option are given to getpwnam(3) and
getgrnam(3) and numeric IDs are not supported.

Giving these options is an error when used with --inetd; use the
facility of inet daemon to achieve the same before spawning git
daemon if needed.

Like many programs that switch user id, the daemon does not reset
environment variables such as $HOME when it runs git programs, e.g.

So switching to "_gitdaemon" at runtime and starting as it through su(1)
is not the same.

> Note that git-daemon does not support any of the standard exploit
> mitigation measures regular OpenBSD daemons provide; there is not
> even support for chroot(8).
> 
> Fix for the port:
This seems like the right direction and I support setups with less
potential to accidentially run things as root, but existing setups might
break.



Re: git-daemon may unexpectedly run as root

2019-07-14 Thread Stuart Henderson
On 2019/07/14 17:18, Klemens Nanni wrote:
> On Sun, Jul 14, 2019 at 03:46:06PM +0200, Stefan Sperling wrote:
> > Overriding gitdaemon_flags in /etc/r.conf.local will cause rc.d to
> > run git-daemon run as root instead of the expected _gitdaemon user.
> Well, you ought to check the existing daemon flags before changing them.
> 
> Admittedly, this is suboptimal and users have to carry the options along
> themselves, but some third-party daemons will not work with `daemon_user`,
> and I believe git-daemon(1) is one of them.
> 
> > 
> > To reproduce, try an rc.conf.local line such as:
> >gitdaemon_flags=--listen=127.0.0.1 /git
> > 
> > This happens because the rc script currently depends on git-daemon itself
> > to switch the user ID, rather than using rc.d's built-in mechanism which
> > forces a UID with su(1). If the user overrides the flags, no UID switch
> > will happen.
> Off the top of my head, I know that this is the case for security/hitch
> and net/tinc as well.  I remember discussion about putting `-u $user'
> into `$daemon' itself to enforce the user for cases where our rc.subr(8)
> framework is not applicable, but there were objections.
> 
> > Anyone exposing git-daemon to the public internet on an OpenBSD system
> > should check their system. This line in rc.conf.local will force the
> > daemon to run under its dedicated user account:
> >gitdaemon_user=_gitdaemon
> This will also (partially?) break git-daemon(1)'s `--inetd' option,
> I think.  From the manual:

You wouldn't be using --inetd in a rcctl-started daemon.

>   --user=, --group=
>   Change daemon’s uid and gid before entering the service loop. When
>   only --user is given without --group, the primary group ID for the
>   user is used. The values of the option are given to getpwnam(3) and
>   getgrnam(3) and numeric IDs are not supported.
> 
>   Giving these options is an error when used with --inetd; use the
>   facility of inet daemon to achieve the same before spawning git
>   daemon if needed.
> 
>   Like many programs that switch user id, the daemon does not reset
>   environment variables such as $HOME when it runs git programs, e.g.
> 
> So switching to "_gitdaemon" at runtime and starting as it through su(1)
> is not the same.
> 
> > Note that git-daemon does not support any of the standard exploit
> > mitigation measures regular OpenBSD daemons provide; there is not
> > even support for chroot(8).
> > 
> > Fix for the port:
> This seems like the right direction and I support setups with less
> potential to accidentially run things as root, but existing setups might
> break.
> 

I think this is likely to work for git-daemon but isn't always going
to work in the general case (sometimes a daemon needs to bind to port <1024,
for example). So maybe it's better if we come up with a more general thing
that can be copied and pasted (after all rc.d/gitdaemon is going to be
present on many users' and devs' machines so it's not a bad place for
a reusable example).

Hardcoding a username in $daemon won't always work, somebody might need
to run as a different uid. Another approach might be a custom rc_start
that starts the daemon as root and adds --user=${daemon_user} etc to the
command line.



Re: git-daemon may unexpectedly run as root

2019-07-14 Thread Stefan Sperling
On Sun, Jul 14, 2019 at 05:18:39PM +0200, Klemens Nanni wrote:
> On Sun, Jul 14, 2019 at 03:46:06PM +0200, Stefan Sperling wrote:
> > Overriding gitdaemon_flags in /etc/r.conf.local will cause rc.d to
> > run git-daemon run as root instead of the expected _gitdaemon user.
> Well, you ought to check the existing daemon flags before changing them.
> 
> Admittedly, this is suboptimal and users have to carry the options along
> themselves, but some third-party daemons will not work with `daemon_user`,
> and I believe git-daemon(1) is one of them.
> 
> > 
> > To reproduce, try an rc.conf.local line such as:
> >gitdaemon_flags=--listen=127.0.0.1 /git
> > 
> > This happens because the rc script currently depends on git-daemon itself
> > to switch the user ID, rather than using rc.d's built-in mechanism which
> > forces a UID with su(1). If the user overrides the flags, no UID switch
> > will happen.
> Off the top of my head, I know that this is the case for security/hitch
> and net/tinc as well.  I remember discussion about putting `-u $user'
> into `$daemon' itself to enforce the user for cases where our rc.subr(8)
> framework is not applicable, but there were objections.

My position is that while we cannot prevent people from changing their
configuration in a risky fashion, the default should be as secure as we
can reasonably make it. I've gotten used to not having daemons, even from
ports land, start up as root. I don't even think about it anymore, I just
take this for granted. I suspect other users have similar expectations.

Setting something like a --listen option should not affect this expectation.
(Unless the service needs a privileged port, of course, which this one
does not.)

> > Anyone exposing git-daemon to the public internet on an OpenBSD system
> > should check their system. This line in rc.conf.local will force the
> > daemon to run under its dedicated user account:
> >gitdaemon_user=_gitdaemon
> This will also (partially?) break git-daemon(1)'s `--inetd' option,
> I think.  From the manual:

Is there any reason to start git-daemon through rc.d(8) in --inetd mode?
git-daemon isn't running persistently in the inetd case. It will be started
by inetd on demand, based on configuration parameters in /etc/inetd.conf.
I don't see how the rc.d script would be involved here in the first place.

>   --user=, --group=
>   Change daemon’s uid and gid before entering the service loop. When
>   only --user is given without --group, the primary group ID for the
>   user is used. The values of the option are given to getpwnam(3) and
>   getgrnam(3) and numeric IDs are not supported.
> 
>   Giving these options is an error when used with --inetd; use the
>   facility of inet daemon to achieve the same before spawning git
>   daemon if needed.
> 
>   Like many programs that switch user id, the daemon does not reset
>   environment variables such as $HOME when it runs git programs, e.g.
> 
> So switching to "_gitdaemon" at runtime and starting as it through su(1)
> is not the same.

I don't understand which difference you mean.
Could you please try to explain your point better?

Are you referring to the environment being different when started
as a non-root user? I would trust rc.d(8) to do the right thing
with the environment.

> > Note that git-daemon does not support any of the standard exploit
> > mitigation measures regular OpenBSD daemons provide; there is not
> > even support for chroot(8).
> > 
> > Fix for the port:
> This seems like the right direction and I support setups with less
> potential to accidentially run things as root, but existing setups might
> break.

Break in what way?

Please consider that any setup that runs this thing as root is a hazard.
Can you name any potential consequences which the proposed change might
introduce which are actually worse than running git-daemon as root?

Even if there were people how wanted to run git-daemon as root on purpose
I wouldn't see any reason for us to support them in doing so.



Re: git-daemon may unexpectedly run as root

2019-07-14 Thread Stefan Sperling
On Sun, Jul 14, 2019 at 10:41:33PM +0100, Stuart Henderson wrote:
> I think this is likely to work for git-daemon but isn't always going
> to work in the general case (sometimes a daemon needs to bind to port <1024,
> for example). So maybe it's better if we come up with a more general thing
> that can be copied and pasted (after all rc.d/gitdaemon is going to be
> present on many users' and devs' machines so it's not a bad place for
> a reusable example).

I see what you mean, but I think it makes sense to have porters deal
with this on a case-by-case basis. Every upstream software has different
requirements and edge cases. In some cases we might decide we want to
limit possibilities provided by upstream (e.g. upstream might be fine
with using a privileged port by default, while we aren't), in some
cases we might trust upstream code to do things right.

Encouraging copy-pasting in this area might result in porters not
considering all their options carefully.

> Hardcoding a username in $daemon won't always work, somebody might need
> to run as a different uid.

My patch still alllows for that. It doesn't tweak $daemon. Rather, it
sets a reasonable default value for $gitdaemon_user which can still be
overridden if desired.

> Another approach might be a custom rc_start
> that starts the daemon as root and adds --user=${daemon_user} etc to the
> command line.

I don't see why we should trust this --user option and give upstream code
a window where it runs as root until it decides to switch UID, if rc.d(8)
can make the entire program start out with an unprivileged UID from the
beginning.



Re: git-daemon may unexpectedly run as root

2019-07-14 Thread Klemens Nanni
On Mon, Jul 15, 2019 at 12:01:59AM +0200, Stefan Sperling wrote:
> Is there any reason to start git-daemon through rc.d(8) in --inetd mode?
No;  I was stupidly short-sighted when looking through git-daemon(1)
with regard to its options and `--user' in particular.

> I don't understand which difference you mean.
> Could you please try to explain your point better?
The daemon itself won't reset the environment, so starting it as root
with `-u _gitdaemon' will preserve stuff like HOME whereas setting
`$daemon_user' will cause it to be started with a properly set
environment.

> Are you referring to the environment being different when started
> as a non-root user? I would trust rc.d(8) to do the right thing
> with the environment.
Yes;  having said the above, I do agree here.  Just wanted to point out
that these two approaches are not the same.

> Break in what way?
Thought of the inetd thing, please disregard.

> Please consider that any setup that runs this thing as root is a hazard.
> Can you name any potential consequences which the proposed change might
> introduce which are actually worse than running git-daemon as root?
Running the daemon on privileged ports as only root may do so, which
would work with `--user _gitdaemon' but not `daemon_user=_gitdaemon',
but that not a bright idea anyway.

Also, git-daemon(1) has `--group' as well:  dropping to a group other
than the user's primary one will only work then started as root.
However, I doubt that people are running such setups.

> Even if there were people how wanted to run git-daemon as root on purpose
> I wouldn't see any reason for us to support them in doing so.
Providing a safe default is good and since my initial doubts were based
on my own stupidity alone (--inetd in rc.d does not make sense),
OK kn.



Re: git-daemon may unexpectedly run as root

2019-07-14 Thread Klemens Nanni
On Mon, Jul 15, 2019 at 12:31:21AM +0200, Stefan Sperling wrote:
> On Sun, Jul 14, 2019 at 10:41:33PM +0100, Stuart Henderson wrote:
> > I think this is likely to work for git-daemon but isn't always going
> > to work in the general case (sometimes a daemon needs to bind to port <1024,
> > for example).
Yes, that was my point.

> > So maybe it's better if we come up with a more general thing
> > that can be copied and pasted (after all rc.d/gitdaemon is going to be
> > present on many users' and devs' machines so it's not a bad place for
> > a reusable example).
This could work, but I have not idea of how it would look like, yet.

> I see what you mean, but I think it makes sense to have porters deal
> with this on a case-by-case basis. Every upstream software has different
> requirements and edge cases. In some cases we might decide we want to
> limit possibilities provided by upstream (e.g. upstream might be fine
> with using a privileged port by default, while we aren't), in some
> cases we might trust upstream code to do things right.
I concur.

> I don't see why we should trust this --user option and give upstream code
> a window where it runs as root until it decides to switch UID, if rc.d(8)
> can make the entire program start out with an unprivileged UID from the
> beginning.
As already said, this is not already possible, but it still is a good
reason to prefer our framework (as the majority of user setting rc.d
scripts in ports already does).



Re: git-daemon may unexpectedly run as root

2019-07-14 Thread Antoine Jacoutot
> > I don't understand which difference you mean.
> > Could you please try to explain your point better?
> The daemon itself won't reset the environment, so starting it as root
> with `-u _gitdaemon' will preserve stuff like HOME whereas setting
> `$daemon_user' will cause it to be started with a properly set
> environment.

How so? What makes it behave differently when both options are started
from rc.d?

> > Are you referring to the environment being different when started
> > as a non-root user? I would trust rc.d(8) to do the right thing
> > with the environment.
> Yes;  having said the above, I do agree here.  Just wanted to point out
> that these two approaches are not the same.
> 
> > Break in what way?
> Thought of the inetd thing, please disregard.
> 
> > Please consider that any setup that runs this thing as root is a hazard.
> > Can you name any potential consequences which the proposed change might
> > introduce which are actually worse than running git-daemon as root?
> Running the daemon on privileged ports as only root may do so, which
> would work with `--user _gitdaemon' but not `daemon_user=_gitdaemon',
> but that not a bright idea anyway.
> 
> Also, git-daemon(1) has `--group' as well:  dropping to a group other
> than the user's primary one will only work then started as root.
> However, I doubt that people are running such setups.
> 
> > Even if there were people how wanted to run git-daemon as root on purpose
> > I wouldn't see any reason for us to support them in doing so.
> Providing a safe default is good and since my initial doubts were based
> on my own stupidity alone (--inetd in rc.d does not make sense),
> OK kn.
> 

-- 
Antoine



Re: git-daemon may unexpectedly run as root

2019-07-15 Thread Klemens Nanni
On Mon, Jul 15, 2019 at 08:05:56AM +0200, Antoine Jacoutot wrote:
> How so? What makes it behave differently when both options are started
> from rc.d?
Both are started from rc.d through `su -l ...',  both get their HOME,
USER, PATH, etc. set - that means different `daemon_user' values will
cause different values in those environment variables.

`daemon_user=root daemon_flags=-u _gitdaemon' will therefore start as
root, drop privileges, but run with HOME=/root as it is not reset.

`daemon_user=_gitdaemon' will therefore start as _gitdaemon, not drop
privileges and keep its proper environment, where everything already
matches the running user.



Re: git-daemon may unexpectedly run as root

2019-07-15 Thread Antoine Jacoutot
On Mon, Jul 15, 2019 at 11:15:55AM +0200, Klemens Nanni wrote:
> On Mon, Jul 15, 2019 at 08:05:56AM +0200, Antoine Jacoutot wrote:
> > How so? What makes it behave differently when both options are started
> > from rc.d?
> Both are started from rc.d through `su -l ...',  both get their HOME,
> USER, PATH, etc. set - that means different `daemon_user' values will
> cause different values in those environment variables.
> 
> `daemon_user=root daemon_flags=-u _gitdaemon' will therefore start as
> root, drop privileges, but run with HOME=/root as it is not reset.
> 
> `daemon_user=_gitdaemon' will therefore start as _gitdaemon, not drop
> privileges and keep its proper environment, where everything already
> matches the running user.
 
Yes I know that, I wrote the framework :-)
My question is how will it make it behave different?

-- 
Antoine