As documented by posix & linux, if the real ID is set or the effective ID is
set to a value not equal to the previous real ID, the saved ID shall be set
to the new effective ID.
---
 sysdeps/mach/hurd/setregid.c | 38 +++++++++++++++++++++++++++++++++++-
 sysdeps/mach/hurd/setreuid.c | 38 +++++++++++++++++++++++++++++++++++-
 2 files changed, 74 insertions(+), 2 deletions(-)

diff --git a/sysdeps/mach/hurd/setregid.c b/sysdeps/mach/hurd/setregid.c
index f68278e39d..4f7a87174a 100644
--- a/sysdeps/mach/hurd/setregid.c
+++ b/sysdeps/mach/hurd/setregid.c
@@ -38,8 +38,14 @@ retry:
       /* Make a new auth handle which has RGID as the real gid,
         and EGID as the first element in the list of effective gids.  */
 
-      gid_t *newgen, *newaux;
+      gid_t *newgen, *newaux, auxbuf[2];
       size_t ngen, naux;
+      gid_t old_rgid, new_egid;
+
+      if (_hurd_id.aux.ngids >= 1)
+       old_rgid = _hurd_id.aux.gids[0];
+      else
+       old_rgid = -1;
 
       newgen = _hurd_id.gen.gids;
       ngen = _hurd_id.gen.ngids;
@@ -74,6 +80,36 @@ retry:
            }
        }
 
+      if (egid != -1)
+       new_egid = egid;
+      else if (ngen >= 1)
+       new_egid = newgen[0];
+      else if (naux >= 1)
+       new_egid = newaux[0];
+      else
+       new_egid = -1;
+
+      if (rgid != -1 || (egid != -1 && new_egid != old_rgid))
+       /* Special-case, set saved ID to new effective ID.  */
+       {
+         if (_hurd_id.aux.ngids < 2)
+           {
+             if (naux >= 1)
+               auxbuf[0] = newaux[0];
+             else
+               auxbuf[0] = old_rgid;
+             auxbuf[1] = new_egid;
+
+             newaux = auxbuf;
+             naux = 2;
+           }
+         else
+           {
+             _hurd_id.aux.gids[1] = new_egid;
+             _hurd_id.valid = 0;
+           }
+       }
+
       err = __USEPORT (AUTH, __auth_makeauth
                       (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0,
                        _hurd_id.gen.uids, _hurd_id.gen.nuids,
diff --git a/sysdeps/mach/hurd/setreuid.c b/sysdeps/mach/hurd/setreuid.c
index 2259551fbc..7647dc5b8d 100644
--- a/sysdeps/mach/hurd/setreuid.c
+++ b/sysdeps/mach/hurd/setreuid.c
@@ -38,8 +38,14 @@ retry:
       /* Make a new auth handle which has RUID as the real uid,
         and EUID as the first element in the list of effective uids.  */
 
-      uid_t *newgen, *newaux;
+      uid_t *newgen, *newaux, auxbuf[2];
       size_t ngen, naux;
+      uid_t old_ruid, new_euid;
+
+      if (_hurd_id.aux.nuids >= 1)
+       old_ruid = _hurd_id.aux.uids[0];
+      else
+       old_ruid = -1;
 
       newgen = _hurd_id.gen.uids;
       ngen = _hurd_id.gen.nuids;
@@ -74,6 +80,36 @@ retry:
            }
        }
 
+      if (euid != -1)
+       new_euid = euid;
+      else if (ngen >= 1)
+       new_euid = newgen[0];
+      else if (naux >= 1)
+       new_euid = newaux[0];
+      else
+       new_euid = -1;
+
+      if (ruid != -1 || (euid != -1 && new_euid != old_ruid))
+       /* Special-case, set saved ID to new effective ID.  */
+       {
+         if (_hurd_id.aux.nuids < 2)
+           {
+             if (naux >= 1)
+               auxbuf[0] = newaux[0];
+             else
+               auxbuf[0] = old_ruid;
+             auxbuf[1] = new_euid;
+
+             newaux = auxbuf;
+             naux = 2;
+           }
+         else
+           {
+             _hurd_id.aux.uids[1] = new_euid;
+             _hurd_id.valid = 0;
+           }
+       }
+
       err = __USEPORT (AUTH, __auth_makeauth
                       (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0,
                        newgen, ngen, newaux, naux,
-- 
2.53.0


Reply via email to