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: