Lack of compatibility in Cpanel's wrappers

Martini-man

Member
Dec 23, 2003
7
0
151
When creating a wrapper starting on root and dropping to a certain unprivileged
user, one should be careful not only when dealing with user and group IDs
(setreuid(),setregid()) but also while handling the groups from which the user
is a member (setgroups()).
If we pick a SUID program (like bin/cpwrap) and just do a setregid(something,
something);setreuid(something, something);execve(...); we are misregarding the
other groups, thus the program executed by execve() will have the groups
belonging to root. At first sight this might not be very bad, but from some
security application's point of view, this is an unforgivable mistake, as some
security programs use the groups in which a user is member to check whether to
allow or block certain operations.
You could address this issue, by using something like this function:
int
fix_groups (char * who)
{
struct group * gr;
gid_t * groups;
int i=0;
char ** p;

while (gr = getgrent ())
{
for (p=gr->gr_mem; *p; *(p++))
if (!strcmp (*p, who))
{
groups = (!i) ? (gid_t *) malloc (sizeof (gid_t)) : (gid_t *)
realloc (groups, (i+1) * sizeof (gid_t));
if (groups == NULL)
return -1
groups = gr->gr_gid;
i++;
break;
}
}
return setgroups (i, groups);
}

Best regards,
Fernando Magro.


------- Comment #1 From Fernando Magro 2006-07-21 14:38 [reply] -------

Oh, I forgot to mention.
The *hack* I posted is for Linux only and the fix_groups() function is just for
you to understand what initgroups() does.
Thus, you could just use initgroups() in your wrappers, and everything would be
fine.