initgroups

219 views
Skip to first unread message

Clay Gerrard

unread,
Feb 6, 2012, 5:48:32 PM2/6/12
to Paste Users
Hello,

I've discovered some esoteric functionality with regards to how paste
serve drops privileges and I'd like to provide some information and
solicit feedback for a path forward.

When starting an application with paster serve as root (e.g. in order
to bind to a privileged port), the effective groups membership of the
processes as returned by 'os.getgroups()' is left as '[0]' (i.e. root)

I don't really consider this a security issue myself, but others may
disagree, as a file that is readable/writable by the root GROUP will
still be accessible by the application started by paster serve as root
even after it "drops privileges" to another user as specified in the
config.

Some folks will suggest that you simply call os.setgroups([]) to
remove all group membership permissions except that explicitly set
with setgid().

http://stackoverflow.com/questions/2699907/dropping-root-permissions-in-python

This is necessary and [probably] sufficient.

However, IMO, the better option is take advantage of
os.initgroups(user, gid), which will set the effective group
permissions for all groups of which the specified user is a member and
also the supplemental group id as provided (in this case from the
command line).

http://docs.python.org/library/os.html#os.initgroups

Unfortunately this system function only became directly available in >
2.7 (http://bugs.python.org/issue7333), but you can emulate the spirit
of the functionality with the grp module:

os.setgroups([e.gr_gid for e in grp.getgrall() if user in e.gr_mem] +
[gid])

In paste.script.serve.change_user_group, you would perform the above
just before the call to os.setgid(gid).

I'd like to see the functionality of paster serve improved in this
regard. Would anyone else be interesting in patching this?

Alternatively suggest which patch would most likely to be accepted?

1) os.setgroups([]) is probably the quickest, but not as useful if you
need the extra permissions of all the user's groups.
2) check hasattr(os, 'initgroups') and call it when available,
otherwise call setgroups([]).
3) check hasattr(os, 'initgroups') and call it when available,
otherwise emulate initgroups using grp.getgrall().
4) always use setgroups and grp to find and set the groups of which
the specified user is a member.

For completeness, another option would be to ctype initgroups:

https://gist.github.com/1755433

As an aside, currently, if a user, but no group is passed in on the
command line os.setgid is not called. I would suggest a better
default when group is not provided (as opposed to leaving the
effective gid as 0) would be to look for a group with the same name as
the user (grp.getgrnam(user)) and print a warning if unable to set a
reasonable group.

Warm Regards,

clayg

Ian Bicking

unread,
Feb 6, 2012, 10:47:59 PM2/6/12
to Clay Gerrard, Paste Users

ctypes definitely isn't a starter; putting that aside, changing to all the groups of the user being switched to seems nicest, especially if you've researched the particular invocation necessary to do that in a backward compatible way ;)  I think no groups would personally confuse me if I hit a permission error due to that.

--
You received this message because you are subscribed to the Google Groups "Paste Users" group.
To post to this group, send email to paste...@googlegroups.com.
To unsubscribe from this group, send email to paste-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/paste-users?hl=en.

Clay Gerrard

unread,
Feb 8, 2012, 1:00:31 AM2/8/12
to Paste Users


On Feb 6, 9:47 pm, Ian Bicking <ianbick...@gmail.com> wrote:
> ctypes definitely isn't a starter

;)

> changing to all the
> groups of the user being switched to seems nicest, especially if you've
> researched the particular invocation necessary to do that in a backward
> compatible way ;)

"researched" probably isn't the right word.

This patch works on my machine, tested 2.6 and 2.7:

https://bitbucket.org/ianb/pastescript/pull-request/3/fix-group-permissions-for-pastescriptserve

-clayg

p.s. sorry about the unrelated .hgignore change - I don't usually use
mercurial

> On Feb 6, 2012 4:48 PM, "Clay Gerrard" <clay.gerr...@gmail.com> wrote:
>
>
>
>
>
>
>
> > Hello,
>
> > I've discovered some esoteric functionality with regards to how paste
> > serve drops privileges and I'd like to provide some information and
> > solicit feedback for a path forward.
>
> > When starting an application with paster serve as root (e.g. in order
> > to bind to a privileged port), the effective groups membership of the
> > processes as returned by 'os.getgroups()' is left as '[0]' (i.e. root)
>
> > I don't really consider this a security issue myself, but others may
> > disagree, as a file that is readable/writable by the root GROUP will
> > still be accessible by the application started by paster serve as root
> > even after it "drops privileges" to another user as specified in the
> > config.
>
> > Some folks will suggest that you simply call os.setgroups([]) to
> > remove all group membership permissions except that explicitly set
> > with setgid().
>
> >http://stackoverflow.com/questions/2699907/dropping-root-permissions-...
Reply all
Reply to author
Forward
0 new messages