Call setgroups() before setgid() to drop supplementary groups.
authorEmil Mikulic <emikulic@gmail.com>
Sat, 27 Dec 2014 13:58:00 +0000 (00:58 +1100)
committerEmil Mikulic <emikulic@gmail.com>
Sat, 27 Dec 2014 13:58:00 +0000 (00:58 +1100)
Pointed out to me by: Pavel Alexeev
Caught by rpmlint

See also: https://www.securecoding.cert.org/confluence/display/seccode/POS36-C.+Observe+correct+revocation+order+while+relinquishing+privileges

conv.c

diff --git a/conv.c b/conv.c
index 265f864..e1ff414 100644 (file)
--- a/conv.c
+++ b/conv.c
 #include "err.h"
 #include <errno.h>
 #include <fcntl.h>
+#include <grp.h>
+#include <limits.h>
 #include <pwd.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
-#include <limits.h>
 
 #define PATH_DEVNULL "/dev/null"
 
@@ -310,6 +311,12 @@ void privdrop(const char *chroot_dir, const char *privdrop_user) {
          err(1, "chroot(\"%s\") failed", chroot_dir);
       verbosef("chrooted into: %s", chroot_dir);
    }
+   {
+      gid_t list[1];
+      list[0] = pw->pw_gid;
+      if (setgroups(1, list) == -1)
+         err(1, "setgroups");
+   }
    if (setgid(pw->pw_gid) == -1)
       err(1, "setgid");
    if (setuid(pw->pw_uid) == -1)