extern int container_p_restore(char *dir_name, bool recover) { int i; slurm_mutex_lock(&context_lock); xfree(state_dir); state_dir = xstrdup(dir_name); _restore_state(state_dir); for (i = 0; i < job_id_count; i++) { if (job_id_array[i] == 0) continue; if (debug_flags & DEBUG_FLAG_JOB_CONT) info("%s: %s job(%u)", plugin_type, recover ? "recovered" : "purging", job_id_array[i]); if (!recover) job_id_array[i] = 0; } slurm_mutex_unlock(&context_lock); return SLURM_SUCCESS; }
int inject_code(int pid, unsigned char *payload, size_t payload_len) { int ret = 0, status = 0; void *payload_addr = NULL, *stack = NULL, *code_cave = NULL, *payload_aligned = NULL; size_t payload_size; // align shellcode size to 32/64-bit boundary payload_size = payload_len + (sizeof(void*) - (payload_len % sizeof(void*))); payload_aligned = malloc(payload_size); CHECK(payload_aligned, "malloc() error"); memset(payload_aligned, 0x90, payload_size); // fill with NOPs memcpy(payload_aligned, payload, payload_len); printf("Injecting into target process %d\n", pid); // attach to process CHECK(ptrace_attach(pid), "Error attaching to target process %d", pid); dprintf("Attached to process"); // wait to make sure process is in ptrace-stop state before continuing, // otherwise we may inadvertently kill the process CHECK(wait_stopped(pid), "Failed to wait until target process in stopped state"); dprintf("Process is in stopped state"); // Wait until process has just returned from a system call before proceeding CHECK(ptrace_next_syscall(pid), "Failed to wait until after next syscall"); dprintf("Process exited from syscall"); // save state CHECK(_save_state(pid), "Failed to state target process state"); dprintf("Saved state of target process"); // allocate payload space CHECK(_mmap_data(pid, payload_size, NULL, 0, 0, &payload_addr), "Failed to allocate space for payload"); dprintf("Allocated space for payload at location %p", payload_addr); // copy payload CHECK(ptrace_writemem(pid, payload_addr, payload_aligned, payload_size), "Failed to copy payload to target process"); dprintf("Wrote payload to target process at address %p", payload_addr); // allocate new stack CHECK(_mmap_data(pid, STACK_SIZE, NULL, 0, 0, &stack), "Failed to allocate space for new stack"); stack += STACK_SIZE; // use top address as stack base, since stack grows downward dprintf("Allocated new stack at location %p", stack); // allocate space for code cave CHECK(_mmap_data(pid, MAX_CODE_SIZE, NULL, 0, 0, &code_cave), "Failed to allocate space for code cave"); dprintf("Allocated space for code cave at location %p", code_cave); // launch payload via clone(2) dprintf("Launching payload in new thread"); CHECK(_launch_payload(pid, code_cave, MAX_CODE_SIZE, stack, STACK_SIZE, payload_addr, payload_size, NULL, 0), "Failed to launch payload"); ret = 1; error: if (payload_aligned) free(payload_aligned); _restore_state(pid); ptrace_detach(pid); return ret; }