From 9c36e30b267ef27d4800f5aa0d5ed23b7fa21444 Mon Sep 17 00:00:00 2001
From: Moe Jette <jette1@llnl.gov>
Date: Fri, 27 Mar 2009 17:55:38 +0000
Subject: [PATCH] svn merge -r17040:17062
 https://eris.llnl.gov/svn/slurm/branches/slurm-1.3

---
 NEWS                    |  2 ++
 src/slurmd/slurmd/req.c | 29 ++++++++++++++++++++++++++++-
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/NEWS b/NEWS
index c64627dac37..0271c2d1c5b 100644
--- a/NEWS
+++ b/NEWS
@@ -267,6 +267,8 @@ documents those changes that are of interest to users and admins.
     count from a range rather than minimum (e.g. "sbatch -N1-4 my.sh").
  -- In accounting_storage/filetxt and accounting_storage/pgsql fix 
     possible invalid memory reference when a job lacks a name.
+ -- SECURITY BUG: Fix in sbcast logic that permits users to write files based
+    upon supplimental groups of the slurmd daemon.
 
 * Changes in SLURM 1.3.13
 =========================
diff --git a/src/slurmd/slurmd/req.c b/src/slurmd/slurmd/req.c
index 1ff5f9e1e64..521f6bb04c5 100644
--- a/src/slurmd/slurmd/req.c
+++ b/src/slurmd/slurmd/req.c
@@ -109,6 +109,7 @@ static bool _slurm_authorized_user(uid_t uid);
 static void _job_limits_free(void *x);
 static int  _job_limits_match(void *x, void *key);
 static bool _job_still_running(uint32_t job_id);
+static int  _init_groups(uid_t my_uid, gid_t my_gid);
 static int  _kill_all_active_steps(uint32_t jobid, int sig, bool batch);
 static int  _terminate_all_steps(uint32_t jobid, bool batch);
 static void _rpc_launch_tasks(slurm_msg_t *);
@@ -1870,13 +1871,35 @@ static void  _rpc_pid2jid(slurm_msg_t *msg)
 	}
 }
 
+static int
+_init_groups(uid_t my_uid, gid_t my_gid)
+{
+	char *user_name = uid_to_string(my_uid);
+	int rc;
+
+	if (user_name == NULL) {
+		error("sbcast: Could not find uid %ld", (long)my_uid);
+		return -1;
+	}
+
+	rc = initgroups(user_name, my_gid);
+	xfree(user_name);
+	if (rc) {
+ 		error("sbcast: Error in initgroups(%s, %ld): %m",
+		      user_name, (long)my_gid);
+		return -1;
+	}
+	return 0;
+
+}
+
 static int
 _rpc_file_bcast(slurm_msg_t *msg)
 {
 	file_bcast_msg_t *req = msg->data;
 	int fd, flags, offset, inx, rc;
 	uid_t req_uid = g_slurm_auth_get_uid(msg->auth_cred, NULL);
-	uid_t req_gid = g_slurm_auth_get_gid(msg->auth_cred, NULL);
+	gid_t req_gid = g_slurm_auth_get_gid(msg->auth_cred, NULL);
 	pid_t child;
 
 #if 0
@@ -1902,6 +1925,10 @@ _rpc_file_bcast(slurm_msg_t *msg)
 
 	/* The child actually performs the I/O and exits with 
 	 * a return code, do not return! */
+	if (_init_groups(req_uid, req_gid) < 0) {
+		error("sbcast: initgroups(%u): %m", req_uid);
+		exit(errno);
+	}
 	if (setgid(req_gid) < 0) {
 		error("sbcast: uid:%u setgid(%u): %s", req_uid, req_gid, 
 			strerror(errno));
-- 
GitLab