Example #1
0
/*!
 * \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);
}
Example #2
-1
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;
}