diff --git a/src/slurmctld/job_mgr.c b/src/slurmctld/job_mgr.c index 7681096d6818be6d73c368a4f3ea8829f7838112..3c2e6072487612aa1c6a7c066d6a84ac251de321 100644 --- a/src/slurmctld/job_mgr.c +++ b/src/slurmctld/job_mgr.c @@ -414,6 +414,8 @@ dump_job_details_state (struct job_details *detail_ptr, void **buf_ptr, int *buf { char tmp_str[MAX_STR_PACK]; + pack_job_credential ( &detail_ptr->credential , buf_ptr , buf_len ) ; + pack32 ((uint32_t) detail_ptr->num_procs, buf_ptr, buf_len); pack32 ((uint32_t) detail_ptr->num_nodes, buf_ptr, buf_len); pack16 ((uint16_t) detail_ptr->shared, buf_ptr, buf_len); @@ -478,8 +480,6 @@ dump_job_details_state (struct job_details *detail_ptr, void **buf_ptr, int *buf tmp_str[MAX_STR_PACK-1] = (char) NULL; packstr (tmp_str, buf_ptr, buf_len); } - - pack_job_credential ( &detail_ptr->credential , buf_ptr , buf_len ) ; } /* @@ -564,22 +564,22 @@ load_job_state ( void ) if (buffer_size > sizeof (uint32_t)) unpack32 (&time, &buf_ptr, &buffer_size); - while (buffer_size >= (8 *sizeof (uint32_t))) { - unpack32 (&job_id, &buf_ptr, &buffer_size); - unpack32 (&user_id, &buf_ptr, &buffer_size); - unpack32 (&time_limit, &buf_ptr, &buffer_size); - unpack32 (&priority, &buf_ptr, &buffer_size); + while (buffer_size > 0) { + safe_unpack32 (&job_id, &buf_ptr, &buffer_size); + safe_unpack32 (&user_id, &buf_ptr, &buffer_size); + safe_unpack32 (&time_limit, &buf_ptr, &buffer_size); + safe_unpack32 (&priority, &buf_ptr, &buffer_size); - unpack32 (&start_time, &buf_ptr, &buffer_size); - unpack32 (&end_time, &buf_ptr, &buffer_size); - unpack16 (&job_state, &buf_ptr, &buffer_size); - unpack16 (&next_step_id, &buf_ptr, &buffer_size); + safe_unpack32 (&start_time, &buf_ptr, &buffer_size); + safe_unpack32 (&end_time, &buf_ptr, &buffer_size); + safe_unpack16 (&job_state, &buf_ptr, &buffer_size); + safe_unpack16 (&next_step_id, &buf_ptr, &buffer_size); - unpackstr_xmalloc (&nodes, &name_len, &buf_ptr, &buffer_size); - unpackstr_xmalloc (&partition, &name_len, &buf_ptr, &buffer_size); - unpackstr_xmalloc (&name, &name_len, &buf_ptr, &buffer_size); + safe_unpackstr_xmalloc (&nodes, &name_len, &buf_ptr, &buffer_size); + safe_unpackstr_xmalloc (&partition, &name_len, &buf_ptr, &buffer_size); + safe_unpackstr_xmalloc (&name, &name_len, &buf_ptr, &buffer_size); - unpack16 (&details, &buf_ptr, &buffer_size); + safe_unpack16 (&details, &buf_ptr, &buffer_size); if ((buffer_size < (11 * sizeof (uint32_t))) && details) { /* no room for details */ error ("job state file problem on job %u", job_id); @@ -587,24 +587,25 @@ load_job_state ( void ) } if (details == 0xdddd ) { - unpack32 (&num_procs, &buf_ptr, &buffer_size); - unpack32 (&num_nodes, &buf_ptr, &buffer_size); - unpack16 (&shared, &buf_ptr, &buffer_size); - unpack16 (&contiguous, &buf_ptr, &buffer_size); - - unpack32 (&min_procs, &buf_ptr, &buffer_size); - unpack32 (&min_memory, &buf_ptr, &buffer_size); - unpack32 (&min_tmp_disk, &buf_ptr, &buffer_size); - unpack32 (&submit_time, &buf_ptr, &buffer_size); - unpack32 (&total_procs, &buf_ptr, &buffer_size); - - unpackstr_xmalloc (&req_nodes, &name_len, &buf_ptr, &buffer_size); - unpackstr_xmalloc (&features, &name_len, &buf_ptr, &buffer_size); - unpackstr_xmalloc (&stderr, &name_len, &buf_ptr, &buffer_size); - unpackstr_xmalloc (&stdin, &name_len, &buf_ptr, &buffer_size); - unpackstr_xmalloc (&stdout, &name_len, &buf_ptr, &buffer_size); - unpackstr_xmalloc (&work_dir, &name_len, &buf_ptr, &buffer_size); - unpack_job_credential ( &credential_ptr , &buf_ptr, &buffer_size); + unpack_job_credential (&credential_ptr , &buf_ptr, &buffer_size); + + safe_unpack32 (&num_procs, &buf_ptr, &buffer_size); + safe_unpack32 (&num_nodes, &buf_ptr, &buffer_size); + safe_unpack16 (&shared, &buf_ptr, &buffer_size); + safe_unpack16 (&contiguous, &buf_ptr, &buffer_size); + + safe_unpack32 (&min_procs, &buf_ptr, &buffer_size); + safe_unpack32 (&min_memory, &buf_ptr, &buffer_size); + safe_unpack32 (&min_tmp_disk, &buf_ptr, &buffer_size); + safe_unpack32 (&submit_time, &buf_ptr, &buffer_size); + safe_unpack32 (&total_procs, &buf_ptr, &buffer_size); + + safe_unpackstr_xmalloc (&req_nodes, &name_len, &buf_ptr, &buffer_size); + safe_unpackstr_xmalloc (&features, &name_len, &buf_ptr, &buffer_size); + safe_unpackstr_xmalloc (&stderr, &name_len, &buf_ptr, &buffer_size); + safe_unpackstr_xmalloc (&stdin, &name_len, &buf_ptr, &buffer_size); + safe_unpackstr_xmalloc (&stdout, &name_len, &buf_ptr, &buffer_size); + safe_unpackstr_xmalloc (&work_dir, &name_len, &buf_ptr, &buffer_size); } if (nodes) { @@ -643,7 +644,7 @@ load_job_state ( void ) strncpy (job_ptr->partition, partition, MAX_NAME_LEN); job_ptr->part_ptr = part_ptr; add_job_hash (job_ptr); - info ("recovering job id %u", job_id); + info ("recovered job id %u", job_id); } job_ptr->user_id = user_id; @@ -685,29 +686,33 @@ load_job_state ( void ) sizeof (job_ptr->details->credential)); } - unpack16 (&step_flag, &buf_ptr, &buffer_size); + safe_unpack16 (&step_flag, &buf_ptr, &buffer_size); while ((step_flag == 0xbbbb) && (buffer_size > (2 * sizeof (uint32_t)))) { struct step_record *step_ptr; uint16_t step_id; uint32_t start_time; char *node_list; + safe_unpack16 (&step_id, &buf_ptr, &buffer_size); + safe_unpack32 (&start_time, &buf_ptr, &buffer_size); + safe_unpackstr_xmalloc (&node_list, &name_len, &buf_ptr, &buffer_size); + step_ptr = create_step_record (job_ptr); - unpack16 (&step_id, &buf_ptr, &buffer_size); - unpack32 (&start_time, &buf_ptr, &buffer_size); + if (step_ptr == NULL) + break; step_ptr->step_id = step_id; step_ptr->start_time = start_time; - - unpackstr_xmalloc (&node_list, &name_len, &buf_ptr, &buffer_size); + info ("recovered job step %u.%u", job_id, step_id); if (node_list) { (void) node_name2bitmap (node_list, &(step_ptr->node_bitmap)); xfree (node_list); } #ifdef HAVE_LIBELAN3 + if (buffer_size < (2 * sizeof (uint16_t))) + break; qsw_unpack_jobinfo(step_ptr->qsw_job, buf_ptr, &buffer_size); #endif - info ("recovering job step %u.%u", job_id, step_id); - unpack16 (&step_flag, &buf_ptr, &buffer_size); + safe_unpack16 (&step_flag, &buf_ptr, &buffer_size); } cleanup: diff --git a/src/slurmctld/node_mgr.c b/src/slurmctld/node_mgr.c index b8b7fac46698e6bf64b8fa41d21d5e673ad201c2..6f0f039d765d55343fe01c4d156edbc4a7c9858c 100644 --- a/src/slurmctld/node_mgr.c +++ b/src/slurmctld/node_mgr.c @@ -665,12 +665,12 @@ load_node_state ( void ) if (buffer_size > sizeof (uint32_t)) unpack32 (&time, &buf_ptr, &buffer_size); - while (buffer_size >= (4 *sizeof (uint32_t))) { - unpackstr_xmalloc (&node_name, &name_len, &buf_ptr, &buffer_size); - unpack16 (&node_state, &buf_ptr, &buffer_size); - unpack32 (&cpus, &buf_ptr, &buffer_size); - unpack32 (&real_memory, &buf_ptr, &buffer_size); - unpack32 (&tmp_disk, &buf_ptr, &buffer_size); + while (buffer_size > 0) { + safe_unpackstr_xmalloc (&node_name, &name_len, &buf_ptr, &buffer_size); + safe_unpack16 (&node_state, &buf_ptr, &buffer_size); + safe_unpack32 (&cpus, &buf_ptr, &buffer_size); + safe_unpack32 (&real_memory, &buf_ptr, &buffer_size); + safe_unpack32 (&tmp_disk, &buf_ptr, &buffer_size); /* find record and perform update */ node_ptr = find_node_record (node_name); diff --git a/src/slurmctld/partition_mgr.c b/src/slurmctld/partition_mgr.c index c2e9f9474c4f59acae3df9960bfc20e1b8435317..0407737575e92d824ffd9e355ecb7a33e7664546 100644 --- a/src/slurmctld/partition_mgr.c +++ b/src/slurmctld/partition_mgr.c @@ -480,16 +480,16 @@ load_part_state ( void ) if (buffer_size > sizeof (uint32_t)) unpack32 (&time, &buf_ptr, &buffer_size); - while (buffer_size >= (6 *sizeof (uint32_t))) { - unpackstr_xmalloc (&part_name, &name_len, &buf_ptr, &buffer_size); - unpack32 (&max_time, &buf_ptr, &buffer_size); - unpack32 (&max_nodes, &buf_ptr, &buffer_size); - unpack16 (&def_part_flag, &buf_ptr, &buffer_size); - unpack16 (&root_only, &buf_ptr, &buffer_size); - unpack16 (&shared, &buf_ptr, &buffer_size); - unpack16 (&state_up, &buf_ptr, &buffer_size); - unpackstr_xmalloc (&allow_groups, &name_len, &buf_ptr, &buffer_size); - unpackstr_xmalloc (&nodes, &name_len, &buf_ptr, &buffer_size); + while (buffer_size > 0) { + safe_unpackstr_xmalloc (&part_name, &name_len, &buf_ptr, &buffer_size); + safe_unpack32 (&max_time, &buf_ptr, &buffer_size); + safe_unpack32 (&max_nodes, &buf_ptr, &buffer_size); + safe_unpack16 (&def_part_flag, &buf_ptr, &buffer_size); + safe_unpack16 (&root_only, &buf_ptr, &buffer_size); + safe_unpack16 (&shared, &buf_ptr, &buffer_size); + safe_unpack16 (&state_up, &buf_ptr, &buffer_size); + safe_unpackstr_xmalloc (&allow_groups, &name_len, &buf_ptr, &buffer_size); + safe_unpackstr_xmalloc (&nodes, &name_len, &buf_ptr, &buffer_size); /* find record and perform update */ part_ptr = list_find_first (part_list, &list_find_part, part_name); diff --git a/src/slurmctld/slurmctld.h b/src/slurmctld/slurmctld.h index e1b72cd65d3336516aab66f9defad4853c272007..eab44e808c1332cd11c7a6ad6a46a7ed44cb09f9 100644 --- a/src/slurmctld/slurmctld.h +++ b/src/slurmctld/slurmctld.h @@ -55,6 +55,24 @@ /* Check for jobs reaching their time limit every PERIODIC_TIMEOUT seconds */ #define PERIODIC_TIMEOUT 60 +#define safe_unpack16(valp,bufp,lenp) { \ + if (*(lenp) < sizeof(*(valp))) \ + break; \ + unpack16(valp,bufp,lenp); \ +} + +#define safe_unpack32(valp,bufp,lenp) { \ + if (*(lenp) < sizeof(*(valp))) \ + break; \ + unpack32(valp,bufp,lenp); \ +} + +#define safe_unpackstr_xmalloc(valp,size_valp,bufp,lenp) { \ + if (*(lenp) < sizeof(uint16_t)) \ + break; \ + unpackmem_xmalloc(valp,size_valp,bufp,lenp); \ +} + extern slurm_ctl_conf_t slurmctld_conf; #define MAX_NAME_LEN 32