File U_14-Drop-reclaim-privileges-to-prevent-security-issue-with-H5Fcreate.patch of Package slurm.32313
From: Alejandro Sanchez <alex@schedmd.com>
Date: Wed Oct 11 12:45:25 2023 -0600
Subject: [PATCH 14/19]Drop/reclaim privileges to prevent security issue with H5Fcreate().
Patch-mainline: Upstream
Git-repo: https://github.com/SchedMD/slurm
Git-commit: 0068aaf60a2451599f1a7fc3017340172a049f24
References: bsc#1216207
Signed-off-by: Egbert Eich <eich@suse.de>
Copy _{drop,reclaim}_privileges() to hdf5 plugin. Ignore the style issues,
just copy this verbatim. Will be cleaned up further on master.
Co-authored-by: Tim Wickberg <tim@schedmd.com>
---
.../hdf5/acct_gather_profile_hdf5.c | 106 ++++++++++++++++++++-
1 file changed, 105 insertions(+), 1 deletion(-)
diff --git a/src/plugins/acct_gather_profile/hdf5/acct_gather_profile_hdf5.c b/src/plugins/acct_gather_profile/hdf5/acct_gather_profile_hdf5.c
index 57eeaa907f..d5a972d7c3 100644
--- a/src/plugins/acct_gather_profile/hdf5/acct_gather_profile_hdf5.c
+++ b/src/plugins/acct_gather_profile/hdf5/acct_gather_profile_hdf5.c
@@ -44,6 +44,7 @@
* Copyright (C) 2002 The Regents of the University of California.
\*****************************************************************************/
+#include <grp.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
@@ -100,6 +101,14 @@ const char plugin_name[] = "AcctGatherProfile hdf5 plugin";
const char plugin_type[] = "acct_gather_profile/hdf5";
const uint32_t plugin_version = SLURM_VERSION_NUMBER;
+struct priv_state {
+ uid_t saved_uid;
+ gid_t saved_gid;
+ gid_t * gid_list;
+ int ngids;
+ char saved_cwd [4096];
+};
+
typedef struct {
char *dir;
uint32_t def;
@@ -132,6 +141,88 @@ static table_t *tables = NULL;
static size_t tables_max_len = 0;
static size_t tables_cur_len = 0;
+/* If get_list is false make sure ps->gid_list is initialized before
+ * hand to prevent xfree.
+ */
+static int
+_drop_privileges(stepd_step_rec_t *job, bool do_setuid,
+ struct priv_state *ps, bool get_list)
+{
+ ps->saved_uid = getuid();
+ ps->saved_gid = getgid();
+
+ if (!getcwd (ps->saved_cwd, sizeof (ps->saved_cwd))) {
+ error ("Unable to get current working directory: %m");
+ strlcpy(ps->saved_cwd, "/tmp", sizeof(ps->saved_cwd));
+ }
+
+ ps->ngids = getgroups(0, NULL);
+ if (ps->ngids == -1) {
+ error("%s: getgroups(): %m", __func__);
+ return -1;
+ }
+ if (get_list) {
+ ps->gid_list = (gid_t *) xmalloc(ps->ngids * sizeof(gid_t));
+
+ if (getgroups(ps->ngids, ps->gid_list) == -1) {
+ error("%s: couldn't get %d groups: %m",
+ __func__, ps->ngids);
+ xfree(ps->gid_list);
+ return -1;
+ }
+ }
+
+ /*
+ * No need to drop privileges if we're not running as root
+ */
+ if (getuid() != (uid_t) 0)
+ return SLURM_SUCCESS;
+
+ if (setegid(job->gid) < 0) {
+ error("setegid: %m");
+ return -1;
+ }
+
+ if (setgroups(job->ngids, job->gids) < 0) {
+ error("setgroups: %m");
+ return -1;
+ }
+
+ if (do_setuid && seteuid(job->uid) < 0) {
+ error("seteuid: %m");
+ return -1;
+ }
+
+ return SLURM_SUCCESS;
+}
+
+static int
+_reclaim_privileges(struct priv_state *ps)
+{
+ int rc = SLURM_SUCCESS;
+
+ /*
+ * No need to reclaim privileges if our uid == job->uid
+ */
+ if (geteuid() == ps->saved_uid)
+ goto done;
+ else if (seteuid(ps->saved_uid) < 0) {
+ error("seteuid: %m");
+ rc = -1;
+ } else if (setegid(ps->saved_gid) < 0) {
+ error("setegid: %m");
+ rc = -1;
+ } else if (setgroups(ps->ngids, ps->gid_list) < 0) {
+ error("setgroups: %m");
+ rc = -1;
+ }
+
+done:
+ xfree(ps->gid_list);
+
+ return rc;
+}
+
static void _reset_slurm_profile_conf(void)
{
xfree(hdf5_conf.dir);
@@ -303,7 +394,7 @@ extern void acct_gather_profile_p_get(enum acct_gather_profile_info info_type,
extern int acct_gather_profile_p_node_step_start(stepd_step_rec_t* job)
{
int rc = SLURM_SUCCESS;
-
+ struct priv_state sprivs = { 0 };
char *profile_file_name;
xassert(running_in_slurmstepd());
@@ -346,11 +437,24 @@ extern int acct_gather_profile_p_node_step_start(stepd_step_rec_t* job)
acct_gather_profile_to_string(g_profile_running),
profile_file_name);
+ if (_drop_privileges(g_job, true, &sprivs, false) < 0) {
+ error("%s: Unable to drop privileges", __func__);
+ xfree(profile_file_name);
+ return SLURM_ERROR;
+ }
+
/*
* Create a new file using the default properties
*/
file_id = H5Fcreate(profile_file_name, H5F_ACC_TRUNC, H5P_DEFAULT,
H5P_DEFAULT);
+
+ if (_reclaim_privileges(&sprivs) < 0) {
+ error("%s: Unable to reclaim privileges", __func__);
+ xfree(profile_file_name);
+ return SLURM_ERROR;
+ }
+
if (chown(profile_file_name, (uid_t)g_job->uid,
(gid_t)g_job->gid) < 0)
error("chown(%s): %m", profile_file_name);