static int do_open_image(struct cr_img *img, int dfd, int type, unsigned long oflags, char *path) { int ret, flags; flags = oflags & ~(O_NOBUF | O_SERVICE); ret = openat(dfd, path, flags, CR_FD_PERM); if (ret < 0) { if (!(flags & O_CREAT) && (errno == ENOENT)) { pr_info("No %s image\n", path); img->_x.fd = EMPTY_IMG_FD; goto skip_magic; } pr_perror("Unable to open %s", path); goto err; } img->_x.fd = ret; if (oflags & O_NOBUF) bfd_setraw(&img->_x); else { if (flags == O_RDONLY) ret = bfdopenr(&img->_x); else ret = bfdopenw(&img->_x); if (ret) goto err; } if (imgset_template[type].magic == RAW_IMAGE_MAGIC) goto skip_magic; if (flags == O_RDONLY) ret = img_check_magic(img, oflags, type, path); else ret = img_write_magic(img, oflags, type); if (ret) goto err; skip_magic: return 0; err: return -1; }
static int do_open_image(struct cr_img *img, int dfd, int type, unsigned long oflags, char *path) { int ret, flags; flags = oflags & ~(O_NOBUF | O_SERVICE | O_FORCE_LOCAL); if (opts.remote && !(oflags & O_FORCE_LOCAL)) { char *snapshot_id = NULL; snapshot_id = get_snapshot_id_from_idx(dfd); if (snapshot_id == NULL) ret = -1; else if (flags == O_RDONLY) { pr_info("do_open_remote_image RDONLY path=%s snapshot_id=%s\n", path, snapshot_id); ret = read_remote_image_connection(snapshot_id, path); } else { pr_info("do_open_remote_image WDONLY path=%s snapshot_id=%s\n", path, snapshot_id); ret = write_remote_image_connection(snapshot_id, path, O_WRONLY); } } else ret = openat(dfd, path, flags, CR_FD_PERM); if (ret < 0) { if (!(flags & O_CREAT) && (errno == ENOENT)) { pr_info("No %s image\n", path); img->_x.fd = EMPTY_IMG_FD; goto skip_magic; } pr_perror("Unable to open %s", path); goto err; } img->_x.fd = ret; if (oflags & O_NOBUF) bfd_setraw(&img->_x); else { if (flags == O_RDONLY) ret = bfdopenr(&img->_x); else ret = bfdopenw(&img->_x); if (ret) goto err; } if (imgset_template[type].magic == RAW_IMAGE_MAGIC) goto skip_magic; if (flags == O_RDONLY) ret = img_check_magic(img, oflags, type, path); else ret = img_write_magic(img, oflags, type); if (ret) goto err; skip_magic: return 0; err: return -1; }
int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list) { struct vma_area *vma_area = NULL; unsigned long start, end, pgoff, prev_end = 0; char r, w, x, s; int ret = -1; struct vma_file_info vfi; struct vma_file_info prev_vfi = {}; DIR *map_files_dir = NULL; struct bfd f; vma_area_list->nr = 0; vma_area_list->nr_aios = 0; vma_area_list->longest = 0; vma_area_list->priv_size = 0; INIT_LIST_HEAD(&vma_area_list->h); f.fd = open_proc(pid, "smaps"); if (f.fd < 0) goto err_n; if (bfdopenr(&f)) goto err_n; map_files_dir = opendir_proc(pid, "map_files"); if (!map_files_dir) /* old kernel? */ goto err; while (1) { int num; char file_path[32]; bool eof; char *str; str = breadline(&f); if (IS_ERR(str)) goto err; eof = (str == NULL); if (!eof && !is_vma_range_fmt(str)) { if (!strncmp(str, "Nonlinear", 9)) { BUG_ON(!vma_area); pr_err("Nonlinear mapping found %016"PRIx64"-%016"PRIx64"\n", vma_area->e->start, vma_area->e->end); /* * VMA is already on list and will be * freed later as list get destroyed. */ vma_area = NULL; goto err; } else if (!strncmp(str, "VmFlags: ", 9)) { BUG_ON(!vma_area); if (parse_vmflags(&str[9], vma_area)) goto err; continue; } else continue; } if (vma_area && vma_list_add(vma_area, vma_area_list, &prev_end, &vfi, &prev_vfi)) goto err; if (eof) break; vma_area = alloc_vma_area(); if (!vma_area) goto err; memzero(file_path, sizeof(file_path)); num = sscanf(str, "%lx-%lx %c%c%c%c %lx %x:%x %lu %31s", &start, &end, &r, &w, &x, &s, &pgoff, &vfi.dev_maj, &vfi.dev_min, &vfi.ino, file_path); if (num < 10) { pr_err("Can't parse: %s\n", str); goto err; } vma_area->e->start = start; vma_area->e->end = end; vma_area->e->pgoff = pgoff; vma_area->e->prot = PROT_NONE; if (r == 'r') vma_area->e->prot |= PROT_READ; if (w == 'w') vma_area->e->prot |= PROT_WRITE; if (x == 'x') vma_area->e->prot |= PROT_EXEC; if (s == 's') vma_area->e->flags = MAP_SHARED; else if (s == 'p') vma_area->e->flags = MAP_PRIVATE; else { pr_err("Unexpected VMA met (%c)\n", s); goto err; } if (handle_vma(pid, vma_area, file_path, map_files_dir, &vfi, &prev_vfi, vma_area_list)) goto err; } vma_area = NULL; ret = 0; err: bclose(&f); err_n: if (map_files_dir) closedir(map_files_dir); xfree(vma_area); return ret; }
int parse_pid_status(pid_t pid, struct proc_status_creds *cr) { struct bfd f; int done = 0; int ret = -1; char *str; f.fd = open_proc(pid, "status"); if (f.fd < 0) { pr_perror("Can't open proc status"); return -1; } if (bfdopenr(&f)) return -1; while (done < 9) { str = breadline(&f); if (str == NULL) break; if (IS_ERR(str)) goto err_parse; if (!strncmp(str, "State:", 6)) { cr->state = str[7]; done++; } if (!strncmp(str, "PPid:", 5)) { if (sscanf(str, "PPid:\t%d", &cr->ppid) != 1) { pr_err("Unable to parse: %s\n", str); goto err_parse; } done++; } if (!strncmp(str, "Uid:", 4)) { if (ids_parse(str + 5, cr->uids)) goto err_parse; done++; } if (!strncmp(str, "Gid:", 4)) { if (ids_parse(str + 5, cr->gids)) goto err_parse; done++; } if (!strncmp(str, "CapInh:", 7)) { if (cap_parse(str + 8, cr->cap_inh)) goto err_parse; done++; } if (!strncmp(str, "CapEff:", 7)) { if (cap_parse(str + 8, cr->cap_eff)) goto err_parse; done++; } if (!strncmp(str, "CapPrm:", 7)) { if (cap_parse(str + 8, cr->cap_prm)) goto err_parse; done++; } if (!strncmp(str, "CapBnd:", 7)) { if (cap_parse(str + 8, cr->cap_bnd)) goto err_parse; done++; } if (!strncmp(str, "Seccomp:", 8)) { if (sscanf(str + 9, "%d", &cr->seccomp_mode) != 1) { goto err_parse; } if (cr->seccomp_mode == SECCOMP_MODE_FILTER) { pr_err("SECCOMP_MODE_FILTER not currently supported\n"); goto err_parse; } done++; } } if (done >= 8) ret = 0; err_parse: if (ret) pr_err("Error parsing proc status file\n"); bclose(&f); return ret; }
static int do_open_image(struct cr_img *img, int dfd, int type, unsigned long oflags, char *path) { int ret, flags; flags = oflags & ~(O_NOBUF | O_SERVICE | O_FORCE_LOCAL); /* * For pages images dedup we need to open images read-write on * restore, that may require proper capabilities, so we ask * usernsd to do it for us */ if (root_ns_mask & CLONE_NEWUSER && type == CR_FD_PAGES && oflags & O_RDWR) { struct openat_args pa = { .flags = flags, .err = 0, .mode = CR_FD_PERM, }; snprintf(pa.path, PATH_MAX, "%s", path); ret = userns_call(userns_openat, UNS_FDOUT, &pa, sizeof(struct openat_args), dfd); if (ret < 0) errno = pa.err; } else ret = openat(dfd, path, flags, CR_FD_PERM); if (ret < 0) { if (!(flags & O_CREAT) && (errno == ENOENT || ret == -ENOENT)) { pr_info("No %s image\n", path); img->_x.fd = EMPTY_IMG_FD; goto skip_magic; } pr_perror("Unable to open %s", path); goto err; } img->_x.fd = ret; if (oflags & O_NOBUF) bfd_setraw(&img->_x); else { if (flags == O_RDONLY) ret = bfdopenr(&img->_x); else ret = bfdopenw(&img->_x); if (ret) goto err; } if (imgset_template[type].magic == RAW_IMAGE_MAGIC) goto skip_magic; if (flags == O_RDONLY) ret = img_check_magic(img, oflags, type, path); else ret = img_write_magic(img, oflags, type); if (ret) goto err; skip_magic: return 0; err: return -1; }