[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: problems with sgid "svnserve"

From: Perry E. Metzger <perry_at_piermont.com>
Date: 2004-02-14 02:38:28 CET

"Perry E. Metzger" <perry@piermont.com> writes:
> So it appears that, on linux (where I was running my tests), if the
> shell is executed and the effective gid != the real gid, the shell (or
> perhaps the kernel, I haven't looked at the source) sets the effective
> gid to the real gid first.

It is bash, being "helpful". I hadn't encountered this ever before
because I rarely use linux, and on most other systems /bin/sh is not
bash.

I've considered a number of solutions -- for now, the best of the bad
alternatives I seem to have is this c program, which I'm running as a
wrapper around "svnserve". I set it setuid root, setgid whatever group
I want the repository to be, and all is well, after a fashion.

I think something like this probably should be included with
subversion in the future, for the benefit of people who want to run
with a setgid svnserve and a repository set writable only to that
gid. Having svnserve itself be setuid root seems like a bad idea --
this program is small enough that it is probably safe.

----------------------------------------------------------------------
/*
 * Wrapper to run the svnserve process setgid.
 * The idea is to avoid the problem that some interpreters like bash
 * invoked by svnserve in hook scripts will reset the effective gid to
 * the real gid, nuking the effect of an ordinary setgid svnserve binary.
 * Sadly, to set the real gid portably, you need to be root, if only
 * for a moment.
 * Also smashes the environment to something known, so that games
 * can't be played to try to break the security of the hook scripts,
 * by setting IFS, PATH, and similar means.
 */
/*
 * Written by Perry Metzger, and placed into the public domain.
 */

#include <stdio.h>
#include <unistd.h>

#define REAL_PATH "/usr/bin/svnserve.real"

char *newenv[] = { "PATH=/bin:/usr/bin", "SHELL=/bin/sh", NULL };

int
main(int argc, char **argv)
{
        if (setgid(getegid()) == -1) {
                perror("setgid(getegid())");
                return 1;
        }

        if (seteuid(getuid()) == -1) {
                perror("seteuid(getuid())");
                return 1;
        }

        execve(REAL_PATH, argv, newenv);
        perror("attempting to exec " REAL_PATH " failed");
        return 1;
}
----------------------------------------------------------------------

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org
Received on Sat Feb 14 02:38:48 2004

This is an archived mail posted to the Subversion Users mailing list.