File pacemaker-libcrmservice-pacemakerd-improve-privilege-dropping.patch of Package pacemaker

commit eaf155fbd9e20b315a9b94869b1ce23e785e2126
Author: Ken Gaillot <kgaillot@redhat.com>
Date:   Fri Jan 19 13:09:20 2018 -0600

    Low: libcrmservice,pacemakerd: improve privilege dropping
    
    Better security that makes rpmlint happy re: POS36-C

Index: pacemaker-1.1.18+20180126.bfe4e8042/cib/main.c
===================================================================
--- pacemaker-1.1.18+20180126.bfe4e8042.orig/cib/main.c
+++ pacemaker-1.1.18+20180126.bfe4e8042/cib/main.c
@@ -172,7 +172,7 @@ main(int argc, char **argv)
                     return 100;
                 }
 
-                rc = initgroups(CRM_DAEMON_GROUP, pwentry->pw_gid);
+                rc = initgroups(CRM_DAEMON_USER, pwentry->pw_gid);
                 if (rc < 0) {
                     crm_perror(LOG_ERR, "Could not setup groups for user %d", pwentry->pw_uid);
                     return 100;
Index: pacemaker-1.1.18+20180126.bfe4e8042/lib/services/services_linux.c
===================================================================
--- pacemaker-1.1.18+20180126.bfe4e8042.orig/lib/services/services_linux.c
+++ pacemaker-1.1.18+20180126.bfe4e8042/lib/services/services_linux.c
@@ -17,6 +17,7 @@
 #include <errno.h>
 #include <unistd.h>
 #include <dirent.h>
+#include <grp.h>
 #include <string.h>
 #include <sys/time.h>
 #include <sys/resource.h>
@@ -427,15 +428,25 @@ action_launch_child(svc_action_t *op)
 
     /* Become the desired user */
     if (op->opaque->uid && (geteuid() == 0)) {
+
+        // If requested, set effective group
         if (op->opaque->gid && (setgid(op->opaque->gid) < 0)) {
-            crm_perror(LOG_ERR, "setting group to %d", op->opaque->gid);
+            crm_perror(LOG_ERR, "Could not set child group to %d", op->opaque->gid);
             _exit(PCMK_OCF_NOT_CONFIGURED);
         }
+
+        // Erase supplementary group list
+        // (We could do initgroups() if we kept a copy of the username)
+        if (setgroups(0, NULL) < 0) {
+            crm_perror(LOG_ERR, "Could not set child groups");
+            _exit(PCMK_OCF_NOT_CONFIGURED);
+        }
+
+        // Set effective user
         if (setuid(op->opaque->uid) < 0) {
             crm_perror(LOG_ERR, "setting user to %d", op->opaque->uid);
             _exit(PCMK_OCF_NOT_CONFIGURED);
         }
-        /* We could do initgroups() here if we kept a copy of the username */
     }
 
     /* execute the RA */
Index: pacemaker-1.1.18+20180126.bfe4e8042/mcp/pacemaker.c
===================================================================
--- pacemaker-1.1.18+20180126.bfe4e8042.orig/mcp/pacemaker.c
+++ pacemaker-1.1.18+20180126.bfe4e8042/mcp/pacemaker.c
@@ -310,19 +310,26 @@ start_child(pcmk_child_t * child)
         opts_default[0] = strdup(child->command);
 
         if(gid) {
+            // Whether we need root group access to talk to cluster layer
+            bool need_root_group = TRUE;
+
             if(stack == pcmk_cluster_corosync) {
-                /* Drop root privileges completely
-                 *
-                 * We can do this because we set uidgid.gid.${gid}=1
-                 * via CMAP which allows these processes to connect to
-                 * corosync
+                /* Corosync clusters can drop root group access, because we set
+                 * uidgid.gid.${gid}=1 via CMAP, which allows these processes to
+                 * connect to corosync.
                  */
-                if (setgid(gid) < 0) {
-                    crm_perror(LOG_ERR, "Could not set group to %d", gid);
-                }
+                need_root_group = FALSE;
+            }
+
+            // Drop root group access if not needed
+            if (!need_root_group && (setgid(gid) < 0)) {
+                crm_perror(LOG_ERR, "Could not set group to %d", gid);
+            }
 
-                /* Keep the root group (so we can access corosync), but add the haclient group (so we can access ipc) */
-            } else if (initgroups(child->uid, gid) < 0) {
+            /* Initialize supplementary groups to only those always granted to
+             * the user, plus haclient (so we can access IPC).
+             */
+            if (initgroups(child->uid, gid) < 0) {
                 crm_err("Cannot initialize groups for %s: %s (%d)", child->uid, pcmk_strerror(errno), errno);
             }
         }