markg has asked for the wisdom of the Perl Monks concerning the following question:

I am having trouble dropping privileges on a system which allows membership to multiple groups at once. I have tried numerous approaches -- setting $) and $(, POSIX::setgid(), and Proc::UID -- and in all situations after I change to 'nogroup' I continue to have membership in root, bin, daemon, etc. Nothing I have found addresses setgid in multi-group systems.

Here is the code and result that I have used to test this. I am running Slackware 10.2 and a 2.4.31 kernel. Any suggestions? Is this a potential bug in Perl?

mgrimes@pip$ cat priv.pl #!/usr/bin/perl use strict; use warnings; print `id`; my ($login,$pass,$uid,$gid) = getpwnam('nobody'); ($<,$>) = ($uid,$uid); ($),$() = ($gid,$gid); print "Dropped privilege\n"; print `id`; print `cat priv_file`; mgrimes@pip$ ll priv_file -rw-r----- 1 root root 11 2006-09-08 15:15 priv_file root@pip$ ./priv.pl uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm) Dropped privilege uid=99(nobody) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(ad +m) Privileged - you shouldn't see this!

Replies are listed 'Best First'.
Re: Dropping Privileges
by Fletch (Bishop) on Sep 09, 2006 at 00:41 UTC

    If you read perlvar carefully it covers this:

    Similarly, a value assigned to $) must also be a space-separated list of numbers. The first number sets the effective gid, and the rest (if any) are passed to setgroups(). To get the effect of an empty list for setgroups(), just repeat the new effective gid; that is, to force an effective gid of 5 and an effectively empty setgroups() list, say $) = "5 5".

    So you probably want "$gid $gid" to drop all groups but $gid. And the truly paranoid will check $! afterwards . . .

      Thanks Fletch. I had read perlvar on $( which doesn't mention how to set the groups. I guess I skimmed over $). Apparently, you have to set the group first as well. I had tried something similar to "5 5" without luck, but I now see it was the order.