/*! * \param[in,out] pc Position calculation data structure. * \param[in] g Maximum index group for the calculation. * * Subsequent calls to gmx_ana_poscalc_update() should use only subsets of * \p g for evaluation. * * The topology should have been set for the collection of which \p pc is * a member. */ void gmx_ana_poscalc_set_maxindex(gmx_ana_poscalc_t *pc, gmx_ana_index_t *g) { set_poscalc_maxindex(pc, g, FALSE); setup_base(pc); }
int main (int argc, char **argv) { char tempdir[] = "/tmp/approot_XXXXXX"; char *base_os; char **images; char *root; int n_images; pid_t child; int child_status = 0; char *app_root; char **mountpoints; int n_mountpoints; int i; uid_t ruid, euid, suid; gid_t rgid, egid, sgid; char cwd_buf[PATH_MAX]; char *cwd; if (argc < 2) fatal ("Too few arguments, need base and at least one image"); base_os = argv[1]; images = &argv[2]; n_images = argc - 2; root = mkdtemp (tempdir); if (root == NULL) fatal ("Can't create root"); if (getresgid (&rgid, &egid, &sgid) < 0) fatal_errno ("getresgid"); if (getresuid (&ruid, &euid, &suid) < 0) fatal_errno ("getresuid"); if ((child = syscall (__NR_clone, SIGCHLD | CLONE_NEWNS, NULL)) < 0) fatal_errno ("clone"); if (child == 0) { /* Child */ /* Disable setuid, new caps etc for children */ if (prctl (PR_SET_NO_NEW_PRIVS, 1) < 0 && errno != EINVAL) fatal_errno ("prctl (PR_SET_NO_NEW_PRIVS)"); else if (prctl (PR_SET_SECUREBITS, SECBIT_NOROOT | SECBIT_NOROOT_LOCKED) < 0) fatal_errno ("prctl (SECBIT_NOROOT)"); /* Don't leak our mounts to the parent namespace */ if (mount (NULL, "/", "none", MS_SLAVE | MS_REC, NULL) < 0) fatal_errno ("mount(/, MS_SLAVE | MS_REC)"); /* Check we're allowed to chdir into base os */ cwd = getcwd (cwd_buf, sizeof (cwd_buf)); if (fsuid_chdir (ruid, base_os) < 0) fatal_errno ("chdir"); if (chdir (cwd) < 0) fatal_errno ("chdir"); if (mount ("tmpfs", root, "tmpfs", MS_MGC_VAL | MS_PRIVATE, NULL) != 0) fatal_errno ("execv"); n_mountpoints = n_images + 1; mountpoints = calloc (n_mountpoints, sizeof (char *)); if (mountpoints == NULL) fatal ("oom"); mountpoints[0] = base_os; for (i = 0; i < n_images; i++) { if (fsuid_access (ruid, images[i], R_OK) < 0) fatal_errno ("access"); mountpoints[i+1] = mount_image (root, images[i]); if (mountpoints[i+1] == NULL) fatal ("mount image %s\n", images[i]); } app_root = make_fs_dir (root, "/root", 0555); if (app_root == NULL) fatal ("make_fs_dir root"); setup_base (app_root); merge_dirs (app_root, mountpoints, n_mountpoints); if (chdir (app_root) < 0) fatal_errno ("chdir"); if (chroot (".") < 0) fatal_errno ("chroot"); /* Switch back to the uid of our invoking process. These calls are * irrevocable - see setuid(2) */ if (setgid (rgid) < 0) fatal_errno ("setgid"); if (setuid (ruid) < 0) fatal_errno ("setuid"); if (execl ("/bin/sh", "/bin/sh", NULL) < 0) fatal_errno ("execl"); } /* Parent */ /* Let's also setuid back in the parent - there's no reason to stay uid 0, and * it's just better to drop privileges. */ if (setgid (rgid) < 0) fatal_errno ("setgid"); if (setuid (ruid) < 0) fatal_errno ("setuid"); if (child == -1) fatal_errno ("clone"); /* Ignore Ctrl-C in parent while waiting */ signal (SIGINT, SIG_IGN); if (waitpid (child, &child_status, 0) < 0) fatal_errno ("waitpid"); rmdir (root); if (WIFEXITED (child_status)) return WEXITSTATUS (child_status); else return 1; }