summaryrefslogtreecommitdiff
path: root/apt-pkg/contrib
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 /apt-pkg/contrib
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
Diffstat (limited to 'apt-pkg/contrib')
-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)