Version in base suite: 22.05.8-4+deb12u1 Base version: slurm-wlm-contrib_22.05.8-4+deb12u1 Target version: slurm-wlm-contrib_22.05.8-4+deb12u2 Base file: /srv/ftp-master.debian.org/ftp/pool/contrib/s/slurm-wlm-contrib/slurm-wlm-contrib_22.05.8-4+deb12u1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/contrib/s/slurm-wlm-contrib/slurm-wlm-contrib_22.05.8-4+deb12u2.dsc changelog | 7 patches/CVE-2023-49933-49936-49937-49938 | 717 +++++++++++++++++++++++++++++++ patches/series | 1 3 files changed, 725 insertions(+) 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 00:11:20.000000000 +0000 +++ slurm-wlm-contrib-22.05.8/debian/changelog 2024-02-03 09:52:11.000000000 +0000 @@ -1,3 +1,10 @@ +slurm-wlm-contrib (22.05.8-4+deb12u2) bookworm-security; urgency=medium + + * Fix CVE-2023-49933, CVE-2023-49936, CVE-2023-49937, CVE-2023-49938 + (Closes: #1062264) + + -- Gennaro Oliva 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-49936-49937-49938 slurm-wlm-contrib-22.05.8/debian/patches/CVE-2023-49933-49936-49937-49938 --- slurm-wlm-contrib-22.05.8/debian/patches/CVE-2023-49933-49936-49937-49938 1970-01-01 00:00:00.000000000 +0000 +++ slurm-wlm-contrib-22.05.8/debian/patches/CVE-2023-49933-49936-49937-49938 2024-02-03 09:50:40.000000000 +0000 @@ -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 +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 00:03:10.000000000 +0000 +++ slurm-wlm-contrib-22.05.8/debian/patches/series 2024-02-03 09:52:11.000000000 +0000 @@ -9,3 +9,4 @@ fix-spelling-error force-nvml CVE-2023-41914 +CVE-2023-49933-49936-49937-49938