summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2015-11-28 00:07:07 +0100
committerDavid Kalnischkies <david@kalnischkies.de>2015-11-28 13:27:06 +0100
commitd5e7aa2a60076bf9924d4a62ad19a04951f4759a (patch)
tree0d0454a29d43320a220ad6db452fb0e1280bd812
parent052a7f48e769c10fb25d5b8adbc71dc085913add (diff)
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
-rw-r--r--apt-pkg/contrib/fileutl.cc17
1 files 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<gid_t[]> 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)