]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
execute: Detect groups added by PAM and merge them with supplementary groups
authorDariusz Gadomski <dgadomski@gmail.com>
Wed, 8 Jan 2020 15:24:45 +0000 (16:24 +0100)
committerDariusz Gadomski <dgadomski@gmail.com>
Mon, 13 Jan 2020 09:29:20 +0000 (10:29 +0100)
src/core/execute.c

index 51b9a454bc8dc57af62b0d188e5bc3398cc50a79..5dc111f714d30ec3fd7477782d9a5d57bcb846ea 100644 (file)
@@ -3018,6 +3018,8 @@ static int exec_child(
         size_t n_fds;
         ExecDirectoryType dt;
         int secure_bits;
+        _cleanup_free_ gid_t *gids_after_pam = NULL;
+        int ngids_after_pam = 0;
 
         assert(unit);
         assert(command);
@@ -3431,6 +3433,12 @@ static int exec_child(
                                 *exit_status = EXIT_PAM;
                                 return log_unit_error_errno(unit, r, "Failed to set up PAM session: %m");
                         }
+
+                        ngids_after_pam = getgroups_alloc(&gids_after_pam);
+                        if (ngids_after_pam < 0) {
+                                *exit_status = EXIT_MEMORY;
+                                return log_unit_error_errno(unit, ngids_after_pam, "Failed to obtain groups after setting up PAM: %m");
+                        }
                 }
         }
 
@@ -3510,7 +3518,22 @@ static int exec_child(
          * This needs to be done after PrivateDevices=y setup as device nodes should be owned by the host's root.
          * For non-root in a userns, devices will be owned by the user/group before the group change, and nobody. */
         if (needs_setuid) {
-                r = enforce_groups(gid, supplementary_gids, ngids);
+                _cleanup_free_ gid_t *gids_to_enforce = NULL;
+                int ngids_to_enforce = 0;
+
+                ngids_to_enforce = merge_gid_lists(supplementary_gids,
+                                                   ngids,
+                                                   gids_after_pam,
+                                                   ngids_after_pam,
+                                                   &gids_to_enforce);
+                if (ngids_to_enforce < 0) {
+                        *exit_status = EXIT_MEMORY;
+                        return log_unit_error_errno(unit,
+                                                    ngids_to_enforce,
+                                                    "Failed to merge group lists. Group membership might be incorrect: %m");
+                }
+
+                r = enforce_groups(gid, gids_to_enforce, ngids_to_enforce);
                 if (r < 0) {
                         *exit_status = EXIT_GROUP;
                         return log_unit_error_errno(unit, r, "Changing group credentials failed: %m");