4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-01-21 05:49:19 +08:00

Cygwin: newgrp: only allow group from supplementary group list

Windows only allows to set the primary group to a group already
present in the TOKEN_GROUP list.  Cygwin OTOH fakes success at
setgid() time, to allow a subsequent call to setuid() to do
the actual account switching.  To have a sane behaviour in the
command line tool, check group membership and disallow to switch
to groups other than those already present in the user token.

Fixes: 8bd56ec873453 ("Cygwin: newgrp: first full version")
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2024-02-24 12:59:28 +01:00
parent 808a95d24d
commit 0e3bb302de
2 changed files with 27 additions and 5 deletions

View File

@ -2116,11 +2116,9 @@ D: on /d type fat (binary,user,noumount)
has been given as argument, a command and its arguments can be
specified on the command line.</para>
<para>Please note that setting the primary group to any arbitrary group
is no privileged operation on Windows. However, even if this group is
not in your current user token, or if the group is in your user token
but marked as <literal>deny-only</literal>, no additional permissions
can be obtained by setting this group as primary group.</para>
<para>The new primary group must be either the old primary group, or
it must be part of the supplementary group list. Setting the primary
group to an arbitrary group is not allowed in Windows.</para>
</refsect1>
<refsect1 id="newgrp-seealso">

View File

@ -136,6 +136,7 @@ main (int argc, const char **argv)
char **child_env;
bool new_child_env = false;
gid_t gid;
int ngrps;
setlocale (LC_ALL, "");
@ -176,6 +177,29 @@ main (int argc, const char **argv)
++argv;
}
/* Windows does not allow to set the primary group to another group if
it's not already part of the supplementary group list. However, our
setgid() allows this, otherwise OpenSSH and other account-switching
processes wouldn't work, given we only actually switch the user
context at setuid() time. Therefore we test this here and don't
allow other groups. */
ngrps = getgroups (0, NULL);
if (ngrps > 0)
{
gid_t *glist = (gid_t *) alloca (ngrps * sizeof (gid_t));
ngrps = getgroups (ngrps, glist);
while (--ngrps >= 0)
if (gid == glist[ngrps])
break;
if (ngrps < 0)
{
fprintf (stderr, "%s: can't switch primary group to '%s'\n",
program_invocation_short_name, gr->gr_name);
return 2;
}
}
/* Set primary group */
if (setgid (gid) != 0)
{