Reputation: 56078
I have an executable that's ug+s
to a non-root user and group. I would like it to leave all the supplementary groups it originally had behind. Is there a way to make this happen? It doesn't look like the setgroups
call allows you to do this if you're not root. And when I try it, I get EPERM
.
It seems like there ought to be a way to lose privileges you previously possessed.
Upvotes: 3
Views: 1944
Reputation: 410
You normally want to change the group list, rather than to drop it, to match your new identity after the suid/sgid-assisted switch. You need the group list to match your new uid (and actually gid too, as the group list usually includes gid itself).
Unfortunately, as was already mentioned,
currently you need CAP_SETGID for calling
initgroups()
. However in an attempt
to solve that, I posted a few proposals
to LKML.
This one
allows to "restrict" a group list, which
is somewhat similar to dropping it, but
doesn't give you any extra access rights
if they were blocked by one of the groups
in a list.
This one actually allows you
to get the correct group list, but you
need a privileged helper process to assist
you with that task.
I personally prefer the second solution as it gives you a correct group list, but the first one is at least very simple and doesn't require any helper process or extra privs.
Unfortunately both patch-sets only yielded 1 review comment each, which means the lack of an interest to this problem among LKML people. Maybe those who are interested in this problem here, can evaluate my patches and offer some more discussion of them in LKML.
Upvotes: 0
Reputation: 56078
The short answer is "A process without CAP_SETGID can't.". And it is by design that setgroups can't be used to remove groups when the process has no privileges. The previous link is to an excellent LWN article detailing why not.
In my particular case, since I'm immediately creating a user namespace, those supplementary groups get mapped to 'nobody' anyway. And so it isn't very important. If it is important, you can use setcap(8)
to set capabilities on a wrapper executable that checks that it's being run by the expected user with the expected group permissions and then drops the groups and drops CAP_SETGID and runs the executable you really want to run. The command you would use to do this is:
sudo setcap cap_setgid+ep wrapper_exe
Be careful though, it's now possible that someone who has a shell on your system can use that executable to run some sort of privilege escalation attack if you did not write it very carefully.
Upvotes: 4