From 3faebe6abc04ea8d632bee4537948ca85479c09a Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Thu, 10 May 2012 15:34:53 -0700 Subject: [PATCH] Hurd: Fix setres[ug]id handling of -1 --- ChangeLog | 6 ++++ sysdeps/mach/hurd/setresgid.c | 76 ++++++++++++++++++++++++++++++++++--------- sysdeps/mach/hurd/setresuid.c | 75 ++++++++++++++++++++++++++++++++++-------- 3 files changed, 128 insertions(+), 29 deletions(-) diff --git a/ChangeLog b/ChangeLog index d244bdb82f..6f59a1ee09 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2012-05-10 Samuel Thibault + + * sysdeps/mach/hurd/setresgid.c (__setresgid): Handle the -1 case, + which preserves existing values. + * sysdeps/mach/hurd/setresuid.c (__setresuid): Likewise. + 2012-05-10 Pino Toscano * hurd/hurdselect.c (_hurd_select): Return EINVAL for negative diff --git a/sysdeps/mach/hurd/setresgid.c b/sysdeps/mach/hurd/setresgid.c index 9d5885beda..eebd364fc6 100644 --- a/sysdeps/mach/hurd/setresgid.c +++ b/sysdeps/mach/hurd/setresgid.c @@ -1,5 +1,5 @@ /* setresgid -- set real group ID, effective group ID, and saved-set group ID - Copyright (C) 2002, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 2002-2012 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,7 +28,6 @@ __setresgid (gid_t rgid, gid_t egid, gid_t sgid) { auth_t newauth; error_t err; - gid_t agids[2] = { rgid, sgid }; HURD_CRITICAL_BEGIN; __mutex_lock (&_hurd_id.lock); @@ -37,31 +36,78 @@ __setresgid (gid_t rgid, gid_t egid, gid_t sgid) if (!err) { /* Make a new auth handle which has EGID as the first element in the - list of effective gids. */ + list of effective gids. */ - if (_hurd_id.gen.ngids > 0) + uid_t *newgen, *newaux; + uid_t auxs[2] = { rgid, sgid }; + size_t ngen, naux; + + newgen = _hurd_id.gen.gids; + ngen = _hurd_id.gen.ngids; + if (egid != -1) + { + if (_hurd_id.gen.ngids == 0) + { + /* No effective gids now. The new set will be just UID. */ + newgen = &egid; + ngen = 1; + } + else + { + _hurd_id.gen.gids[0] = egid; + _hurd_id.valid = 0; + } + } + + newaux = _hurd_id.aux.gids; + naux = _hurd_id.aux.ngids; + if (rgid != -1) { - _hurd_id.gen.gids[0] = egid; - _hurd_id.valid = 0; + if (_hurd_id.aux.ngids == 0) + { + newaux = &rgid; + naux = 1; + } + else + { + _hurd_id.aux.gids[0] = rgid; + _hurd_id.valid = 0; + } } - if (_hurd_id.aux.ngids > 1) + + if (sgid != -1) { - _hurd_id.aux.gids[0] = rgid; - _hurd_id.aux.gids[1] = sgid; - _hurd_id.valid = 0; + if (rgid == -1) + { + if (_hurd_id.aux.ngids >= 1) + auxs[0] = _hurd_id.aux.gids[0]; + else if (_hurd_id.gen.ngids >= 1) + auxs[0] = _hurd_id.gen.gids[0]; + else + /* Not even an effective GID. + Fall back to the only GID we have. */ + auxs[0] = sgid; + } + if (_hurd_id.aux.ngids <= 1) + { + /* No saved gids now. The new set will be just UID. */ + newaux = auxs; + naux = 2; + } + else + { + _hurd_id.aux.gids[1] = sgid; + _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, _hurd_id.aux.uids, _hurd_id.aux.nuids, - _hurd_id.gen.ngids ? _hurd_id.gen.gids : &egid, - _hurd_id.gen.ngids ?: 1, - _hurd_id.aux.ngids > 1 ? _hurd_id.aux.gids : agids, - _hurd_id.aux.ngids > 1 ? _hurd_id.aux.ngids : 2, + newgen, ngen, newaux, naux, &newauth)); } - __mutex_unlock (&_hurd_id.lock); HURD_CRITICAL_END; diff --git a/sysdeps/mach/hurd/setresuid.c b/sysdeps/mach/hurd/setresuid.c index 35aea85876..751763f5a9 100644 --- a/sysdeps/mach/hurd/setresuid.c +++ b/sysdeps/mach/hurd/setresuid.c @@ -1,5 +1,5 @@ /* setresuid -- set real user ID, effective user ID, and saved-set user ID - Copyright (C) 2002, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 2002-2012 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,7 +28,6 @@ __setresuid (uid_t ruid, uid_t euid, uid_t suid) { auth_t newauth; error_t err; - uid_t auids[2] = { ruid, suid }; HURD_CRITICAL_BEGIN; __mutex_lock (&_hurd_id.lock); @@ -37,26 +36,74 @@ __setresuid (uid_t ruid, uid_t euid, uid_t suid) if (!err) { /* Make a new auth handle which has EUID as the first element in the - list of effective uids. */ + list of effective uids. */ - if (_hurd_id.gen.nuids > 0) + uid_t *newgen, *newaux; + uid_t auxs[2] = { ruid, suid }; + size_t ngen, naux; + + newgen = _hurd_id.gen.uids; + ngen = _hurd_id.gen.nuids; + if (euid != -1) { - _hurd_id.gen.uids[0] = euid; - _hurd_id.valid = 0; + if (_hurd_id.gen.nuids == 0) + { + /* No effective uids now. The new set will be just UID. */ + newgen = &euid; + ngen = 1; + } + else + { + _hurd_id.gen.uids[0] = euid; + _hurd_id.valid = 0; + } } - if (_hurd_id.aux.nuids > 1) + + newaux = _hurd_id.aux.uids; + naux = _hurd_id.aux.nuids; + if (ruid != -1) + { + if (_hurd_id.aux.nuids == 0) + { + newaux = &ruid; + naux = 1; + } + else + { + _hurd_id.aux.uids[0] = ruid; + _hurd_id.valid = 0; + } + } + + if (suid != -1) { - _hurd_id.aux.uids[0] = ruid; - _hurd_id.aux.uids[1] = suid; - _hurd_id.valid = 0; + if (ruid == -1) + { + if (_hurd_id.aux.nuids >= 1) + auxs[0] = _hurd_id.aux.uids[0]; + else if (_hurd_id.gen.nuids >= 1) + auxs[0] = _hurd_id.gen.uids[0]; + else + /* Not even an effective UID. + Fall back to the only UID we have. */ + auxs[0] = suid; + } + if (_hurd_id.aux.nuids <= 1) + { + /* No saved uids now. The new set will be just UID. */ + newaux = auxs; + naux = 2; + } + else + { + _hurd_id.aux.uids[1] = suid; + _hurd_id.valid = 0; + } } err = __USEPORT (AUTH, __auth_makeauth (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0, - _hurd_id.gen.nuids ? _hurd_id.gen.uids : &euid, - _hurd_id.gen.nuids ?: 1, - _hurd_id.aux.nuids > 1 ? _hurd_id.aux.uids : auids, - _hurd_id.aux.nuids > 1 ? _hurd_id.aux.nuids : 2, + newgen, ngen, newaux, naux, _hurd_id.gen.gids, _hurd_id.gen.ngids, _hurd_id.aux.gids, _hurd_id.aux.ngids, &newauth)); -- 2.11.4.GIT