[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1058720: slurm-wlm: CVE-2023-49933 CVE-2023-49935 CVE-2023-49936 CVE-2023-49937 CVE-2023-49938



Ciao Salvatore,

On Sun, Jan 28, 2024 at 11:37:34AM +0100, Salvatore Bonaccorso wrote:
> Reviewing your uploaded changes, the changelog mentions
> CVE-2023-49935, but believe his was not affecting 22.05.8.  Let's
> still release with that in the changelog, the security-tracker should
> be already correct on that.

Sorry about that, I also forgot to build and upload the contrib package
(check #1062264) I have uploaded at the same url and attached the debdiff.

https://people.debian.org/~oliva/slurm-wlm-22.05.8-4+deb12u2

> Do you have any progress for unstable/trixie so we do not have a
> regression once after the DSA is released?

I'm working on it this week end. It is a major release upgrade. I hope
to release it at the beginning of next week.

Best regards,
-- 
Gennaro Oliva
diff -Nru slurm-wlm-contrib-22.05.8/debian/changelog slurm-wlm-contrib-22.05.8/debian/changelog
--- slurm-wlm-contrib-22.05.8/debian/changelog	2023-10-14 02:11:20.000000000 +0200
+++ slurm-wlm-contrib-22.05.8/debian/changelog	2024-02-03 10:52:11.000000000 +0100
@@ -1,3 +1,10 @@
+slurm-wlm-contrib (22.05.8-4+deb12u2) bookworm-security; urgency=medium
+
+  * Fix CVE-2023-49933, CVE-2023-49935, CVE-2023-49936, CVE-2023-49937,
+        CVE-2023-49938 (Closes: #1062264)
+
+ -- Gennaro Oliva <oliva@debian.org>  Sat, 03 Feb 2024 10:52:11 +0100
+
 slurm-wlm-contrib (22.05.8-4+deb12u1) bookworm-security; urgency=medium
 
   * Fix CVE-2023-41914
diff -Nru slurm-wlm-contrib-22.05.8/debian/patches/CVE-2023-49933-49935-49936-49937-49938 slurm-wlm-contrib-22.05.8/debian/patches/CVE-2023-49933-49935-49936-49937-49938
--- slurm-wlm-contrib-22.05.8/debian/patches/CVE-2023-49933-49935-49936-49937-49938	1970-01-01 01:00:00.000000000 +0100
+++ slurm-wlm-contrib-22.05.8/debian/patches/CVE-2023-49933-49935-49936-49937-49938	2024-02-03 10:50:40.000000000 +0100
@@ -0,0 +1,717 @@
+Description: Fix CVE-2023-49933/49935/49936/49937/49938
+ Fix improper enforcement of message integrity during transmission in a
+ communication channel that allows attackers to modify RPC traffic in a way that
+ bypasses message hash checks. Fix a NULL pointer dereference that leads to denial of
+ service. Fix a double free that allows attackers to cause a denial of service or
+ possibly execute arbitrary code. Fix incorrect access control that can enable
+ an attacker to modify their extended group list that is used with the sbcast
+ subsystem, and open files with an unauthorized set of extended groups.
+Author: Tim Wickberg <tim@schedmd.com>
+Last-Update: 2023-12-25
+
+diff --git a/src/common/pack.c b/src/common/pack.c
+index b7e048b02d..75238188a9 100644
+--- a/src/common/pack.c
++++ b/src/common/pack.c
+@@ -521,17 +521,16 @@ void pack16_array(uint16_t *valp, uint32_t size_val, buf_t *buffer)
+  */
+ int unpack16_array(uint16_t **valp, uint32_t *size_val, buf_t *buffer)
+ {
+-	uint32_t i = 0;
+-
+-	if (unpack32(size_val, buffer))
+-		return SLURM_ERROR;
+-
+-	*valp = xmalloc_nz((*size_val) * sizeof(uint16_t));
+-	for (i = 0; i < *size_val; i++) {
+-		if (unpack16((*valp) + i, buffer))
+-			return SLURM_ERROR;
+-	}
++	*valp = NULL;
++	safe_unpack32(size_val, buffer);
++	safe_xcalloc(*valp, *size_val, sizeof(uint16_t));
++	for (uint32_t i = 0; i < *size_val; i++)
++		safe_unpack16(&(*valp)[i], buffer);
+ 	return SLURM_SUCCESS;
++
++unpack_error:
++	xfree(*valp);
++	return SLURM_ERROR;
+ }
+ 
+ /*
+@@ -555,17 +554,16 @@ void pack32_array(uint32_t *valp, uint32_t size_val, buf_t *buffer)
+  */
+ int unpack32_array(uint32_t **valp, uint32_t *size_val, buf_t *buffer)
+ {
+-	uint32_t i = 0;
+-
+-	if (unpack32(size_val, buffer))
+-		return SLURM_ERROR;
+-
+-	*valp = xmalloc_nz((*size_val) * sizeof(uint32_t));
+-	for (i = 0; i < *size_val; i++) {
+-		if (unpack32((*valp) + i, buffer))
+-			return SLURM_ERROR;
+-	}
++	*valp = NULL;
++	safe_unpack32(size_val, buffer);
++	safe_xcalloc(*valp, *size_val, sizeof(uint32_t));
++	for (uint32_t i = 0; i < *size_val; i++)
++		safe_unpack32(&(*valp)[i], buffer);
+ 	return SLURM_SUCCESS;
++
++unpack_error:
++	xfree(*valp);
++	return SLURM_ERROR;
+ }
+ 
+ /*
+@@ -588,17 +586,16 @@ void pack64_array(uint64_t *valp, uint32_t size_val, buf_t *buffer)
+  */
+ int unpack64_array(uint64_t **valp, uint32_t *size_val, buf_t *buffer)
+ {
+-	uint32_t i = 0;
+-
+-	if (unpack32(size_val, buffer))
+-		return SLURM_ERROR;
+-
+-	*valp = xmalloc_nz((*size_val) * sizeof(uint64_t));
+-	for (i = 0; i < *size_val; i++) {
+-		if (unpack64((*valp) + i, buffer))
+-			return SLURM_ERROR;
+-	}
++	*valp = NULL;
++	safe_unpack32(size_val, buffer);
++	safe_xcalloc(*valp, *size_val, sizeof(uint64_t));
++	for (uint32_t i = 0; i < *size_val; i++)
++		safe_unpack64(&(*valp)[i], buffer);
+ 	return SLURM_SUCCESS;
++
++unpack_error:
++	xfree(*valp);
++	return SLURM_ERROR;
+ }
+ 
+ void packdouble_array(double *valp, uint32_t size_val, buf_t *buffer)
+@@ -616,17 +613,16 @@ void packdouble_array(double *valp, uint32_t size_val, buf_t *buffer)
+ 
+ int unpackdouble_array(double **valp, uint32_t* size_val, buf_t *buffer)
+ {
+-	uint32_t i = 0;
+-
+-	if (unpack32(size_val, buffer))
+-		return SLURM_ERROR;
+-
+-	*valp = xmalloc_nz((*size_val) * sizeof(double));
+-	for (i = 0; i < *size_val; i++) {
+-		if (unpackdouble((*valp) + i, buffer))
+-			return SLURM_ERROR;
+-	}
++	*valp = NULL;
++	safe_unpack32(size_val, buffer);
++	safe_xcalloc(*valp, *size_val, sizeof(double));
++	for (uint32_t i = 0; i < *size_val; i++)
++		safe_unpackdouble(&(*valp)[i], buffer);
+ 	return SLURM_SUCCESS;
++
++unpack_error:
++	xfree(*valp);
++	return SLURM_ERROR;
+ }
+ 
+ void packlongdouble_array(long double *valp, uint32_t size_val, buf_t *buffer)
+@@ -645,17 +641,16 @@ void packlongdouble_array(long double *valp, uint32_t size_val, buf_t *buffer)
+ int unpacklongdouble_array(long double **valp, uint32_t *size_val,
+ 			   buf_t *buffer)
+ {
+-	uint32_t i = 0;
+-
+-	if (unpack32(size_val, buffer))
+-		return SLURM_ERROR;
+-
+-	*valp = xmalloc_nz((*size_val) * sizeof(long double));
+-	for (i = 0; i < *size_val; i++) {
+-		if (unpacklongdouble((*valp) + i, buffer))
+-			return SLURM_ERROR;
+-	}
++	*valp = NULL;
++	safe_unpack32(size_val, buffer);
++	safe_xcalloc(*valp, *size_val, sizeof(long double));
++	for (uint32_t i = 0; i < *size_val; i++)
++		safe_unpacklongdouble(&(*valp)[i], buffer);
+ 	return SLURM_SUCCESS;
++
++unpack_error:
++	xfree(*valp);
++	return SLURM_ERROR;
+ }
+ 
+ 
+@@ -835,28 +830,29 @@ extern void packmem(void *valp, uint32_t size_val, buf_t *buffer)
+  */
+ int unpackmem_ptr(char **valp, uint32_t *size_valp, buf_t *buffer)
+ {
+-	uint32_t ns;
+-
+-	if (remaining_buf(buffer) < sizeof(ns))
+-		return SLURM_ERROR;
++	*valp = NULL;
++	safe_unpack32(size_valp, buffer);
+ 
+-	memcpy(&ns, &buffer->head[buffer->processed], sizeof(ns));
+-	*size_valp = ntohl(ns);
+-	buffer->processed += sizeof(ns);
++	if (!*size_valp)
++		return SLURM_SUCCESS;
+ 
+ 	if (*size_valp > MAX_PACK_MEM_LEN) {
+ 		error("%s: Buffer to be unpacked is too large (%u > %u)",
+ 		      __func__, *size_valp, MAX_PACK_MEM_LEN);
+-		return SLURM_ERROR;
++		goto unpack_error;
+ 	}
+-	else if (*size_valp > 0) {
+-		if (remaining_buf(buffer) < *size_valp)
+-			return SLURM_ERROR;
+-		*valp = &buffer->head[buffer->processed];
+-		buffer->processed += *size_valp;
+-	} else
+-		*valp = NULL;
++
++	if (remaining_buf(buffer) < *size_valp)
++		goto unpack_error;
++
++	*valp = &buffer->head[buffer->processed];
++	buffer->processed += *size_valp;
++
+ 	return SLURM_SUCCESS;
++
++unpack_error:
++	*size_valp = 0;
++	return SLURM_ERROR;
+ }
+ 
+ /*
+@@ -870,30 +866,30 @@ int unpackmem_ptr(char **valp, uint32_t *size_valp, buf_t *buffer)
+  */
+ int unpackmem_xmalloc(char **valp, uint32_t *size_valp, buf_t *buffer)
+ {
+-	uint32_t ns;
+-
+-	if (remaining_buf(buffer) < sizeof(ns))
+-		return SLURM_ERROR;
++	*valp = NULL;
++	safe_unpack32(size_valp, buffer);
+ 
+-	memcpy(&ns, &buffer->head[buffer->processed], sizeof(ns));
+-	*size_valp = ntohl(ns);
+-	buffer->processed += sizeof(ns);
++	if (!*size_valp)
++		return SLURM_SUCCESS;
+ 
+ 	if (*size_valp > MAX_PACK_MEM_LEN) {
+ 		error("%s: Buffer to be unpacked is too large (%u > %u)",
+ 		      __func__, *size_valp, MAX_PACK_MEM_LEN);
+-		return SLURM_ERROR;
++		goto unpack_error;
+ 	}
+-	else if (*size_valp > 0) {
+-		if (remaining_buf(buffer) < *size_valp)
+-			return SLURM_ERROR;
+-		*valp = xmalloc_nz(*size_valp);
+-		memcpy(*valp, &buffer->head[buffer->processed],
+-		       *size_valp);
+-		buffer->processed += *size_valp;
+-	} else
+-		*valp = NULL;
++
++	if (remaining_buf(buffer) < *size_valp)
++		goto unpack_error;
++
++	safe_xmalloc(*valp, *size_valp);
++	memcpy(*valp, &buffer->head[buffer->processed], *size_valp);
++	buffer->processed += *size_valp;
++
+ 	return SLURM_SUCCESS;
++
++unpack_error:
++	*size_valp = 0;
++	return SLURM_ERROR;
+ }
+ 
+ /*
+@@ -907,34 +903,31 @@ int unpackmem_xmalloc(char **valp, uint32_t *size_valp, buf_t *buffer)
+  */
+ int unpackmem_malloc(char **valp, uint32_t *size_valp, buf_t *buffer)
+ {
+-	uint32_t ns;
+-
+-	if (remaining_buf(buffer) < sizeof(ns))
+-		return SLURM_ERROR;
++	*valp = NULL;
++	safe_unpack32(size_valp, buffer);
+ 
+-	memcpy(&ns, &buffer->head[buffer->processed], sizeof(ns));
+-	*size_valp = ntohl(ns);
+-	buffer->processed += sizeof(ns);
++	if (!*size_valp)
++		return SLURM_SUCCESS;
+ 
+ 	if (*size_valp > MAX_PACK_MEM_LEN) {
+ 		error("%s: Buffer to be unpacked is too large (%u > %u)",
+ 		      __func__, *size_valp, MAX_PACK_MEM_LEN);
+-		return SLURM_ERROR;
++		goto unpack_error;
+ 	}
+-	else if (*size_valp > 0) {
+-		if (remaining_buf(buffer) < *size_valp)
+-			return SLURM_ERROR;
+-		*valp = malloc(*size_valp);
+-		if (*valp == NULL) {
+-			log_oom(__FILE__, __LINE__, __func__);
+-			abort();
+-		}
+-		memcpy(*valp, &buffer->head[buffer->processed],
+-		       *size_valp);
+-		buffer->processed += *size_valp;
+-	} else
+-		*valp = NULL;
++
++	if (remaining_buf(buffer) < *size_valp)
++		goto unpack_error;
++
++	if (!(*valp = malloc(*size_valp)))
++		goto unpack_error;
++	memcpy(*valp, &buffer->head[buffer->processed], *size_valp);
++	buffer->processed += *size_valp;
++
+ 	return SLURM_SUCCESS;
++
++unpack_error:
++	*size_valp = 0;
++	return SLURM_ERROR;
+ }
+ 
+ /*
+@@ -953,52 +946,49 @@ int unpackmem_malloc(char **valp, uint32_t *size_valp, buf_t *buffer)
+  */
+ int unpackstr_xmalloc_escaped(char **valp, uint32_t *size_valp, buf_t *buffer)
+ {
+-	uint32_t ns;
++	uint32_t cnt;
++	char *copy = NULL, *str, tmp;
+ 
+-	if (remaining_buf(buffer) < sizeof(ns))
+-		return SLURM_ERROR;
++	*valp = NULL;
++	safe_unpack32(size_valp, buffer);
+ 
+-	memcpy(&ns, &buffer->head[buffer->processed], sizeof(ns));
+-	*size_valp = ntohl(ns);
+-	buffer->processed += sizeof(ns);
++	if (!*size_valp)
++		return SLURM_SUCCESS;
+ 
+ 	if (*size_valp > MAX_PACK_MEM_LEN) {
+ 		error("%s: Buffer to be unpacked is too large (%u > %u)",
+ 		      __func__, *size_valp, MAX_PACK_MEM_LEN);
+ 		return SLURM_ERROR;
+-	} else if (*size_valp > 0) {
+-		uint32_t cnt = *size_valp;
+-
+-		if (remaining_buf(buffer) < cnt)
+-			return SLURM_ERROR;
+-
+-		/* make a buffer 2 times the size just to be safe */
+-		*valp = xmalloc_nz((cnt * 2) + 1);
+-		if (*valp) {
+-			char *copy = NULL, *str, tmp;
+-			uint32_t i;
+-			copy = *valp;
+-			str = &buffer->head[buffer->processed];
+-
+-			for (i = 0; i < cnt && *str; i++) {
+-				tmp = *str++;
+-				if ((tmp == '\\') || (tmp == '\'')) {
+-					*copy++ = '\\';
+-					(*size_valp)++;
+-				}
+-
+-				*copy++ = tmp;
+-			}
+-
+-			/* Since we used xmalloc_nz, terminate the string. */
+-			*copy++ = '\0';
++	}
++
++	cnt = *size_valp;
++
++	if (remaining_buf(buffer) < cnt)
++		return SLURM_ERROR;
++
++	/* make a buffer 2 times the size just to be safe */
++	safe_xmalloc(*valp, (cnt * 2) + 1);
++	copy = *valp;
++	str = &buffer->head[buffer->processed];
++
++	for (uint32_t i = 0; i < cnt && *str; i++) {
++		tmp = *str++;
++		if ((tmp == '\\') || (tmp == '\'')) {
++			*copy++ = '\\';
++			(*size_valp)++;
+ 		}
+ 
+-		/* add the original value since that is what we processed */
+-		buffer->processed += cnt;
+-	} else
+-		*valp = NULL;
++		*copy++ = tmp;
++	}
++
++	/* add the original value since that is what we processed */
++	buffer->processed += cnt;
++
+ 	return SLURM_SUCCESS;
++
++unpack_error:
++	*size_valp = 0;
++	return SLURM_ERROR;
+ }
+ 
+ int unpackstr_xmalloc_chooser(char **valp, uint32_t *size_valp, buf_t *buf)
+@@ -1050,29 +1040,24 @@ void packstr_array(char **valp, uint32_t size_val, buf_t *buffer)
+  */
+ int unpackstr_array(char ***valp, uint32_t *size_valp, buf_t *buffer)
+ {
+-	int i;
+-	uint32_t ns;
+-	uint32_t uint32_tmp;
++	*valp = NULL;
++	safe_unpack32(size_valp, buffer);
+ 
+-	if (remaining_buf(buffer) < sizeof(ns))
+-		return SLURM_ERROR;
++	if (!*size_valp)
++		return SLURM_SUCCESS;
+ 
+-	memcpy(&ns, &buffer->head[buffer->processed], sizeof(ns));
+-	*size_valp = ntohl(ns);
+-	buffer->processed += sizeof(ns);
++	if (*size_valp > MAX_PACK_MEM_LEN)
++		goto unpack_error;
+ 
+-	if (*size_valp > 0) {
+-		*valp = xcalloc(*size_valp + 1, sizeof(char *));
+-		for (i = 0; i < *size_valp; i++) {
+-			if (unpackmem_xmalloc(&(*valp)[i], &uint32_tmp, buffer)) {
+-				*size_valp = 0;
+-				xfree_array(*valp);
+-				return SLURM_ERROR;
+-			}
+-		}
+-	} else
+-		*valp = NULL;
++	safe_xcalloc(*valp, *size_valp + 1, sizeof(char *));
++	for (uint32_t i = 0; i < *size_valp; i++)
++		safe_unpackstr(&(*valp)[i], buffer);
+ 	return SLURM_SUCCESS;
++
++unpack_error:
++	*size_valp = 0;
++	xfree_array(*valp);
++	return SLURM_ERROR;
+ }
+ 
+ /*
+diff --git a/src/common/slurm_cred.c b/src/common/slurm_cred.c
+index be333665fb..51f0f42e3d 100644
+--- a/src/common/slurm_cred.c
++++ b/src/common/slurm_cred.c
+@@ -185,7 +185,8 @@ typedef struct {
+ 	int   (*cred_verify_sign)	(void *key, char *buffer,
+ 					 uint32_t buf_size,
+ 					 char *signature,
+-					 uint32_t sig_size);
++					 uint32_t sig_size,
++					 bool replay_okay);
+ 	const char *(*cred_str_error)	(int);
+ } slurm_cred_ops_t;
+ 
+@@ -269,8 +270,6 @@ static void _cred_state_pack(slurm_cred_ctx_t ctx, buf_t *buffer);
+ static void _job_state_pack_one(job_state_t *j, buf_t *buffer);
+ static void _cred_state_pack_one(cred_state_t *s, buf_t *buffer);
+ 
+-static void _sbast_cache_add(sbcast_cred_t *sbcast_cred);
+-
+ static int _slurm_cred_init(void)
+ {
+ 	char *tok;
+@@ -1773,11 +1772,11 @@ static void _cred_verify_signature(slurm_cred_ctx_t ctx, slurm_cred_t *cred)
+ 
+ 	rc = (*(ops.cred_verify_sign))(ctx->key, start, len,
+ 				       cred->signature,
+-				       cred->siglen);
++				       cred->siglen, true);
+ 	if (rc && _exkey_is_valid(ctx)) {
+ 		rc = (*(ops.cred_verify_sign))(ctx->exkey, start, len,
+ 					       cred->signature,
+-					       cred->siglen);
++					       cred->siglen, true);
+ 	}
+ 
+ 	if (rc) {
+@@ -2444,25 +2443,6 @@ void delete_sbcast_cred(sbcast_cred_t *sbcast_cred)
+ 	xfree(sbcast_cred);
+ }
+ 
+-static void _sbast_cache_add(sbcast_cred_t *sbcast_cred)
+-{
+-	int i;
+-	uint32_t sig_num = 0;
+-	struct sbcast_cache *new_cache_rec;
+-
+-	/* Using two bytes at a time gives us a larger number
+-	 * and reduces the possibility of a duplicate value */
+-	for (i = 0; i < sbcast_cred->siglen; i += 2) {
+-		sig_num += (sbcast_cred->signature[i] << 8) +
+-			   sbcast_cred->signature[i+1];
+-	}
+-
+-	new_cache_rec = xmalloc(sizeof(struct sbcast_cache));
+-	new_cache_rec->expire = sbcast_cred->expiration;
+-	new_cache_rec->value  = sig_num;
+-	list_append(sbcast_cache_list, new_cache_rec);
+-}
+-
+ /* Extract contents of an sbcast credential verifying the digital signature.
+  * NOTE: We can only perform the full credential validation once with
+  *	Munge without generating a credential replay error, so we only
+@@ -2477,9 +2457,7 @@ sbcast_cred_arg_t *extract_sbcast_cred(slurm_cred_ctx_t ctx,
+ 				       uint16_t protocol_version)
+ {
+ 	sbcast_cred_arg_t *arg;
+-	struct sbcast_cache *next_cache_rec;
+-	uint32_t sig_num = 0;
+-	int i, rc;
++	int rc;
+ 	time_t now = time(NULL);
+ 	buf_t *buffer;
+ 
+@@ -2491,14 +2469,14 @@ sbcast_cred_arg_t *extract_sbcast_cred(slurm_cred_ctx_t ctx,
+ 	if (now > sbcast_cred->expiration)
+ 		return NULL;
+ 
+-	if (block_no == 1 && !(flags & FILE_BCAST_SO)) {
++	if (block_no == 1) {
+ 		buffer = init_buf(4096);
+ 		_pack_sbcast_cred(sbcast_cred, buffer, protocol_version);
+ 		/* NOTE: the verification checks that the credential was
+ 		 * created by SlurmUser or root */
+ 		rc = (*(ops.cred_verify_sign)) (
+ 			ctx->key, get_buf_data(buffer), get_buf_offset(buffer),
+-			sbcast_cred->signature, sbcast_cred->siglen);
++			sbcast_cred->signature, sbcast_cred->siglen, false);
+ 		free_buf(buffer);
+ 
+ 		if (rc) {
+@@ -2506,51 +2484,6 @@ sbcast_cred_arg_t *extract_sbcast_cred(slurm_cred_ctx_t ctx,
+ 			      (*(ops.cred_str_error))(rc));
+ 			return NULL;
+ 		}
+-		_sbast_cache_add(sbcast_cred);
+-
+-	} else {
+-		char *err_str = NULL;
+-		bool cache_match_found = false;
+-		ListIterator sbcast_iter;
+-		for (i = 0; i < sbcast_cred->siglen; i += 2) {
+-			sig_num += (sbcast_cred->signature[i] << 8) +
+-				   sbcast_cred->signature[i+1];
+-		}
+-
+-		sbcast_iter = list_iterator_create(sbcast_cache_list);
+-		while ((next_cache_rec =
+-			(struct sbcast_cache *) list_next(sbcast_iter))) {
+-			if ((next_cache_rec->expire == sbcast_cred->expiration) &&
+-			    (next_cache_rec->value  == sig_num)) {
+-				cache_match_found = true;
+-				break;
+-			}
+-			if (next_cache_rec->expire <= now)
+-				list_delete_item(sbcast_iter);
+-		}
+-		list_iterator_destroy(sbcast_iter);
+-
+-		if (!cache_match_found) {
+-			error("sbcast_cred verify: signature not in cache");
+-			if (SLURM_DIFFTIME(now, cred_restart_time) > 60)
+-				return NULL;	/* restarted >60 secs ago */
+-			buffer = init_buf(4096);
+-			_pack_sbcast_cred(sbcast_cred, buffer,
+-					  protocol_version);
+-			rc = (*(ops.cred_verify_sign)) (
+-				ctx->key, get_buf_data(buffer),
+-				get_buf_offset(buffer),
+-				sbcast_cred->signature, sbcast_cred->siglen);
+-			free_buf(buffer);
+-			if (rc)
+-				err_str = (char *)(*(ops.cred_str_error))(rc);
+-			if (err_str && xstrcmp(err_str, "Credential replayed")){
+-				error("sbcast_cred verify: %s", err_str);
+-				return NULL;
+-			}
+-			info("sbcast_cred verify: signature revalidated");
+-			_sbast_cache_add(sbcast_cred);
+-		}
+ 	}
+ 
+ 	arg = xmalloc(sizeof(sbcast_cred_arg_t));
+diff --git a/src/common/slurm_protocol_api.c b/src/common/slurm_protocol_api.c
+index daaca01aab..f8d8c4e466 100644
+--- a/src/common/slurm_protocol_api.c
++++ b/src/common/slurm_protocol_api.c
+@@ -1091,7 +1091,7 @@ extern int slurm_unpack_received_msg(slurm_msg_t *msg, int fd, buf_t *buffer)
+ 
+ 	msg->body_offset =  get_buf_offset(buffer);
+ 
+-	if ((header.body_length > remaining_buf(buffer)) ||
++	if ((header.body_length != remaining_buf(buffer)) ||
+ 	    _check_hash(buffer, &header, msg, auth_cred) ||
+ 	    (unpack_msg(msg, buffer) != SLURM_SUCCESS)) {
+ 		rc = ESLURM_PROTOCOL_INCOMPLETE_PACKET;
+@@ -1380,7 +1380,7 @@ List slurm_receive_msgs(int fd, int steps, int timeout)
+ 	msg.msg_type = header.msg_type;
+ 	msg.flags = header.flags;
+ 
+-	if ((header.body_length > remaining_buf(buffer)) ||
++	if ((header.body_length != remaining_buf(buffer)) ||
+ 	    _check_hash(buffer, &header, &msg, auth_cred) ||
+ 	    (unpack_msg(&msg, buffer) != SLURM_SUCCESS)) {
+ 		(void) auth_g_destroy(auth_cred);
+@@ -1804,7 +1804,7 @@ int slurm_receive_msg_and_forward(int fd, slurm_addr_t *orig_addr,
+ 	msg->msg_type = header.msg_type;
+ 	msg->flags = header.flags;
+ 
+-	if ( (header.body_length > remaining_buf(buffer)) ||
++	if ((header.body_length != remaining_buf(buffer)) ||
+ 	    _check_hash(buffer, &header, msg, auth_cred) ||
+ 	     (unpack_msg(msg, buffer) != SLURM_SUCCESS) ) {
+ 		(void) auth_g_destroy(auth_cred);
+@@ -2119,7 +2119,7 @@ extern int slurm_unpack_addr_array(slurm_addr_t **addr_array_ptr,
+ 	slurm_addr_t *addr_array = NULL;
+ 
+ 	safe_unpack32(size_val, buffer);
+-	addr_array = xcalloc(*size_val, sizeof(slurm_addr_t));
++	safe_xcalloc(addr_array, *size_val, sizeof(slurm_addr_t));
+ 
+ 	for (int i = 0; i < *size_val; i++) {
+ 		if (slurm_unpack_addr_no_alloc(&addr_array[i], buffer))
+diff --git a/src/common/slurm_protocol_pack.c b/src/common/slurm_protocol_pack.c
+index 1bd356687c..ca385ba57a 100644
+--- a/src/common/slurm_protocol_pack.c
++++ b/src/common/slurm_protocol_pack.c
+@@ -7719,6 +7719,7 @@ static int _unpack_node_reg_resp(
+ 
+ unpack_error:
+ 	slurm_free_node_reg_resp_msg(msg_ptr);
++	*msg = NULL;
+ 	return SLURM_ERROR;
+ }
+ 
+@@ -13915,6 +13916,15 @@ unpack_msg(slurm_msg_t * msg, buf_t *buffer)
+ 	if (rc) {
+ 		error("Malformed RPC of type %s(%u) received",
+ 		      rpc_num2string(msg->msg_type), msg->msg_type);
++
++		/*
++		 * The unpack functions should not leave this set on error,
++		 * doing so would likely result in a double xfree() if we
++		 * did not proactively clear it. (Which, instead, may cause
++		 * a memory leak. But that's preferrable.)
++		 */
++		xassert(msg->data);
++		msg->data = NULL;
+ 	}
+ 	return rc;
+ }
+diff --git a/src/common/slurm_protocol_socket.c b/src/common/slurm_protocol_socket.c
+index ad064516ac..b245d71d5d 100644
+--- a/src/common/slurm_protocol_socket.c
++++ b/src/common/slurm_protocol_socket.c
+@@ -144,7 +144,8 @@ extern ssize_t slurm_msg_recvfrom_timeout(int fd, char **pbuf, size_t *lenp,
+ 	/*
+ 	 *  Allocate memory on heap for message
+ 	 */
+-	*pbuf = xmalloc_nz(msglen);
++	if (!(*pbuf = try_xmalloc(msglen)))
++		slurm_seterrno_ret(ENOMEM);
+ 
+ 	if (slurm_recv_timeout(fd, *pbuf, msglen, 0, tmout) != msglen) {
+ 		xfree(*pbuf);
+diff --git a/src/plugins/cred/munge/cred_munge.c b/src/plugins/cred/munge/cred_munge.c
+index e7d052eddc..1c2b3f174a 100644
+--- a/src/plugins/cred/munge/cred_munge.c
++++ b/src/plugins/cred/munge/cred_munge.c
+@@ -234,7 +234,8 @@ again:
+ }
+ 
+ extern int cred_p_verify_sign(void *key, char *buffer, uint32_t buf_size,
+-			      char *signature, uint32_t sig_size)
++			      char *signature, uint32_t sig_size,
++			      bool replay_okay)
+ {
+ 	int retry = RETRY_COUNT;
+ 	uid_t uid;
+@@ -245,6 +246,10 @@ extern int cred_p_verify_sign(void *key, char *buffer, uint32_t buf_size,
+ 	munge_err_t err;
+ 	munge_ctx_t ctx = (munge_ctx_t) key;
+ 
++#ifdef MULTIPLE_SLURMD
++	replay_okay = true;
++#endif
++
+ again:
+ 	err = munge_decode(signature, ctx, &buf_out, &buf_out_size,
+ 			   &uid, &gid);
+@@ -259,20 +264,17 @@ again:
+ 		if (err == EMUNGE_SOCKET)
+ 			error("If munged is up, restart with --num-threads=10");
+ 
+-#ifdef MULTIPLE_SLURMD
+ 		if (err != EMUNGE_CRED_REPLAYED) {
+ 			rc = err;
+ 			goto end_it;
+-		} else {
+-			debug2("We had a replayed credential, but this is expected in multiple slurmd mode.");
+ 		}
+-#else
+-		if (err == EMUNGE_CRED_REPLAYED)
++
++		if (!replay_okay) {
+ 			rc = ESIG_CRED_REPLAYED;
+-		else
+-			rc = err;
+-		goto end_it;
+-#endif
++			goto end_it;
++		}
++
++		debug2("We had a replayed credential, but this is expected.");
+ 	}
+ 
+ 	if ((uid != slurm_conf.slurm_user_id) && (uid != 0)) {
+diff --git a/src/plugins/cred/none/cred_none.c b/src/plugins/cred/none/cred_none.c
+index e89ec17822..1ee42b1ef1 100644
+--- a/src/plugins/cred/none/cred_none.c
++++ b/src/plugins/cred/none/cred_none.c
+@@ -129,7 +129,8 @@ extern int cred_p_sign(void *key, char *buffer, int buf_size,
+ }
+ 
+ extern int cred_p_verify_sign(void *key, char *buffer, uint32_t buf_size,
+-			      char *signature, uint32_t sig_size)
++			      char *signature, uint32_t sig_size,
++			      bool replay_okay)
+ {
+ 	char *correct_signature = "fake signature";
+ 	if (xstrncmp(signature, correct_signature, sig_size))
diff -Nru slurm-wlm-contrib-22.05.8/debian/patches/series slurm-wlm-contrib-22.05.8/debian/patches/series
--- slurm-wlm-contrib-22.05.8/debian/patches/series	2023-10-14 02:03:10.000000000 +0200
+++ slurm-wlm-contrib-22.05.8/debian/patches/series	2024-02-03 10:50:40.000000000 +0100
@@ -9,3 +9,4 @@
 fix-spelling-error
 force-nvml
 CVE-2023-41914
+CVE-2023-49933-49935-49936-49937-49938

Reply to: