void do_pb_show_plain(int fd, int type, int single_entry, void (*payload_hadler)(int fd, void *obj), const char *pretty_fmt) { pb_pr_ctl_t ctl = {NULL, single_entry, pretty_fmt}; void (*handle_payload)(int fd, void *obj); if (!cr_pb_descs[type].pb_desc) { pr_err("Wrong object requested %d\n", type); return; } handle_payload = (payload_hadler) ? : pb_no_payload; while (1) { void *obj; if (pb_read_one_eof(fd, &obj, type) <= 0) break; ctl.arg = (void *)cr_pb_descs[type].pb_desc; pb_show_msg(obj, &ctl); handle_payload(fd, obj); cr_pb_descs[type].free(obj, NULL); if (single_entry) break; pr_msg("\n"); } }
int collect_image(struct collect_image_info *cinfo) { int fd, ret; void *(*o_alloc)(size_t size) = malloc; void (*o_free)(void *ptr) = free; pr_info("Collecting %d/%d (flags %x)\n", cinfo->fd_type, cinfo->pb_type, cinfo->flags); fd = open_image(cinfo->fd_type, O_RSTR); if (fd < 0) { if ((cinfo->flags & COLLECT_OPTIONAL) && (errno == ENOENT)) return 0; else return -1; } if (cinfo->flags & COLLECT_SHARED) { o_alloc = shmalloc; o_free = shfree_last; } while (1) { void *obj; ProtobufCMessage *msg; if (cinfo->priv_size) { ret = -1; obj = o_alloc(cinfo->priv_size); if (!obj) break; } else obj = NULL; ret = pb_read_one_eof(fd, &msg, cinfo->pb_type); if (ret <= 0) { o_free(obj); break; } ret = cinfo->collect(obj, msg); if (ret < 0) { o_free(obj); cr_pb_descs[cinfo->pb_type].free(msg, NULL); break; } if (!cinfo->priv_size) cr_pb_descs[cinfo->pb_type].free(msg, NULL); } close(fd); pr_debug(" `- ... done\n"); return ret; }
int prepare_seccomp_filters(void) { struct cr_img *img; int ret; img = open_image(CR_FD_SECCOMP, O_RSTR); if (!img) return -1; ret = pb_read_one_eof(img, &se, PB_SECCOMP); close_image(img); if (ret <= 0) return 0; /* there were no filters */ BUG_ON(!se); return 0; }
static int copy_file_from_chunks(struct cr_img *img, int fd, size_t file_size) { if (ftruncate(fd, file_size) < 0) { pr_perror("Can't make file size"); return -1; } while (1) { int ret; GhostChunkEntry *ce; ret = pb_read_one_eof(img, &ce, PB_GHOST_CHUNK); if (ret <= 0) return ret; if (copy_chunk_to_file(img_raw_fd(img), fd, ce->off, ce->len)) return -1; ghost_chunk_entry__free_unpacked(ce, NULL); } }
static int __collect_image(int fd_t, int obj_t, unsigned size, int (*collect)(void *obj, ProtobufCMessage *msg), void * (*alloc)(size_t size), void (*free)(void *ptr)) { int fd, ret; fd = open_image_ro(fd_t); if (fd < 0) return -1; while (1) { void *obj; ProtobufCMessage *msg; if (size) { ret = -1; obj = alloc(size); if (!obj) break; } else obj = NULL; ret = pb_read_one_eof(fd, &msg, obj_t); if (ret <= 0) { free(obj); break; } ret = collect(obj, msg); if (ret < 0) { free(obj); cr_pb_descs[obj_t].free(msg, NULL); break; } } close(fd); return ret; }
static int prepare_ipc_shm(int pid) { int ret; struct cr_img *img; pr_info("Restoring IPC shared memory\n"); img = open_image(CR_FD_IPCNS_SHM, O_RSTR, pid); if (!img) return -1; while (1) { IpcShmEntry *shm; ret = pb_read_one_eof(img, &shm, PB_IPC_SHM); if (ret < 0) { pr_err("Failed to read IPC shared memory segment\n"); ret = -EIO; goto err; } if (ret == 0) break; pr_info_ipc_shm(shm); ret = prepare_ipc_shm_seg(img, shm); ipc_shm_entry__free_unpacked(shm, NULL); if (ret < 0) { pr_err("Failed to prepare shm segment\n"); goto err; } } close_image(img); return 0; err: close_image(img); return ret; }
static int prepare_ipc_msg(int pid) { int ret; struct cr_img *img; pr_info("Restoring IPC message queues\n"); img = open_image(CR_FD_IPCNS_MSG, O_RSTR, pid); if (!img) return -1; while (1) { IpcMsgEntry *msq; ret = pb_read_one_eof(img, &msq, PB_IPCNS_MSG_ENT); if (ret < 0) { pr_err("Failed to read IPC messages queue\n"); ret = -EIO; goto err; } if (ret == 0) break; pr_info_ipc_msg_entry(msq); ret = prepare_ipc_msg_queue(img, msq); ipc_msg_entry__free_unpacked(msq, NULL); if (ret < 0) { pr_err("Failed to prepare messages queue\n"); goto err; } } close_image(img); return 0; err: close_image(img); return ret; }
static int prepare_ipc_sem(int pid) { int ret; struct cr_img *img; pr_info("Restoring IPC semaphores sets\n"); img = open_image(CR_FD_IPCNS_SEM, O_RSTR, pid); if (!img) return -1; while (1) { IpcSemEntry *sem; ret = pb_read_one_eof(img, &sem, PB_IPC_SEM); if (ret < 0) { ret = -EIO; goto err; } if (ret == 0) break; pr_info_ipc_sem_entry(sem); ret = prepare_ipc_sem_desc(img, sem); ipc_sem_entry__free_unpacked(sem, NULL); if (ret < 0) { pr_err("Failed to prepare semaphores set\n"); goto err; } } close_image(img); return 0; err: close_image(img); return ret; }
int prepare_shmem_pid(int pid) { int fd, ret = -1; VmaEntry *vi; fd = open_image(CR_FD_VMAS, O_RSTR, pid); if (fd < 0) { if (errno == ENOENT) return 0; else return -1; } while (1) { ret = pb_read_one_eof(fd, &vi, PB_VMA); if (ret <= 0) break; pr_info("vma 0x%"PRIx64" 0x%"PRIx64"\n", vi->start, vi->end); if (!vma_entry_is(vi, VMA_ANON_SHARED) || vma_entry_is(vi, VMA_AREA_SYSVIPC)) { vma_entry__free_unpacked(vi, NULL); continue; } ret = collect_shmem(pid, vi); vma_entry__free_unpacked(vi, NULL); if (ret) break; } close(fd); return ret; }
static int restore_shmem_content(void *addr, struct shmem_info *si) { int fd, fd_pg, ret = 0; fd = open_image(CR_FD_SHMEM_PAGEMAP, O_RSTR, si->shmid); if (fd < 0) { fd_pg = open_image(CR_FD_SHM_PAGES_OLD, O_RSTR, si->shmid); if (fd_pg < 0) goto err_unmap; } else { fd_pg = open_pages_image(O_RSTR, fd); if (fd_pg < 0) goto out_close; } while (1) { unsigned long vaddr; unsigned nr_pages; if (fd >= 0) { PagemapEntry *pe; ret = pb_read_one_eof(fd, &pe, PB_PAGEMAP); if (ret <= 0) break; vaddr = (unsigned long)decode_pointer(pe->vaddr); nr_pages = pe->nr_pages; pagemap_entry__free_unpacked(pe, NULL); } else { __u64 img_vaddr; ret = read_img_eof(fd_pg, &img_vaddr); if (ret <= 0) break; vaddr = (unsigned long)decode_pointer(img_vaddr); nr_pages = 1; } if (vaddr + nr_pages * PAGE_SIZE > si->size) break; ret = read(fd_pg, addr + vaddr, nr_pages * PAGE_SIZE); if (ret != nr_pages * PAGE_SIZE) { ret = -1; break; } } close_safe(&fd_pg); close_safe(&fd); return ret; out_close: close_safe(&fd); err_unmap: munmap(addr, si->size); return -1; }