From d5e7aa2a60076bf9924d4a62ad19a04951f4759a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 28 Nov 2015 00:07:07 +0100 Subject: [PATCH] show the group we failed to drop via setgroups This also deals with the unlikely case of groups being mentioned multiple times or if the effective group isn't mentioned at all. In practice, it is a debugging aid through like for #806475. Git-Dch: Ignore --- apt-pkg/contrib/fileutl.cc | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 46de63417..f754b313e 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -2322,12 +2322,17 @@ bool DropPrivileges() /*{{{*/ return _error->Errno("seteuid", "Failed to seteuid"); #endif - // Verify that the user has only a single group, and the correct one - gid_t groups[1]; - if (getgroups(1, groups) != 1) - return _error->Errno("getgroups", "Could not get new groups"); - if (groups[0] != pw->pw_gid) - return _error->Error("Could not switch group"); + // Verify that the user isn't still in any supplementary groups + long const ngroups_max = sysconf(_SC_NGROUPS_MAX); + std::unique_ptr gidlist(new gid_t[ngroups_max]); + if (unlikely(gidlist == NULL)) + return _error->Error("Allocation of a list of size %lu for getgroups failed", ngroups_max); + ssize_t gidlist_nr; + if ((gidlist_nr = getgroups(ngroups_max, gidlist.get())) < 0) + return _error->Errno("getgroups", "Could not get new groups (%lu)", ngroups_max); + for (ssize_t i = 0; i < gidlist_nr; ++i) + if (gidlist[i] != pw->pw_gid) + return _error->Error("Could not switch group, user %s is still in group %d", toUser.c_str(), gidlist[i]); // Verify that gid, egid, uid, and euid changed if (getgid() != pw->pw_gid) -- 2.45.2