The Secure Programming Cookbook for C and C++ says that:

"Ancillary groups are inherited by a process from its parent process, and they can only be altered by a process with superuser privileges. Therefore, if a process with superuser privileges is dropping these privileges, it must also be sure to drop any ancillary groups it may have. This is achieved by calling setgroups( ) with a single group, which is the real group ID for the process." [1.3, emphasis mine]

What is the rationale for doing the above rather than just setgroups(0, NULL); that is, en empty list?

Is there some portability problem with pushing an empty list of supplementary groups?

If not, what is achieved by installing the real GID of a process as an ancillary group? Is the issue that if the real GID is not among the ancillaries, and some other GID is effective, then the process is not effectively a member of that group? That doesn't seem like a security issue and is actually a feature. In any case, this is in the context of dropping privileges, so that real GID is about to become the effective one anyway. If we are about to end up with the situation getresgid() == < 1, 1, 1 >, what is the use of arranging for getgroups() == { 1 } versus getgroups() == { }?

1 Answer 1


It does look like portability. E.g this posting on the Samba mailing list with a patch included, subject line, "setgroups requires at least one group":

"On some operating systems (in this case BSD/OS 4.2) setgroups must be given at least one group. When no other groups are wanted, it is given the same group as the desired effective group (as seen in sendmail)."

This kind of thing is worth mentioning when making a recommendation about a practice.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .