]> git.saurik.com Git - apt.git/commitdiff
show the group we failed to drop via setgroups
authorDavid Kalnischkies <david@kalnischkies.de>
Fri, 27 Nov 2015 23:07:07 +0000 (00:07 +0100)
committerDavid Kalnischkies <david@kalnischkies.de>
Sat, 28 Nov 2015 12:27:06 +0000 (13:27 +0100)
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

index 46de6341726207bdb7f275578054c76d9115b5e8..f754b313e500c187e58706d809bd9527a00dd383 100644 (file)
@@ -2322,12 +2322,17 @@ bool DropPrivileges()                                                   /*{{{*/
       return _error->Errno("seteuid", "Failed to seteuid");
 #endif
 
       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)
 
    // Verify that gid, egid, uid, and euid changed
    if (getgid() != pw->pw_gid)