Esempio n. 1
0
void main(int argc, char **argv) {
  uid_t uid = getuid();
  uid_t gid = getgid();
  char *sandbox_root;
  char **cmd_args;

  if(argc < 3) {
    fprintf(stderr, "Usage: sandbox_root command...\n");
    exit(-1);
  }

  new_root = argv[1];
  cmd_args = argv+2;

  /* 1. Unshare. From here onwards, we have most root-equiv capabilities until we execve-ed, FIXME LWN article here. */
  // FIXME try clone here, just to see if that works too.
  check("unshare", unshare(CLONE_NEWNS | CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWUTS));
  /* 2. Fork once, so we become the parent of the new process id space and can mount proc */
  fork_once();

  /* 3. Set UID/GID maps, FIXME LWN article here */
  write_file("/proc/self/setgroups", "deny");
  write_file("/proc/self/uid_map", aasprintf("%d %d 1", uid, uid));
  write_file("/proc/self/gid_map", aasprintf("%d %d 1", gid, gid));

  /* 4. Mount minimal fstab */
  mount_fstab();

  /* 5. Pivot into the new root */
  pivot();

  /* 6. Exec */
  check("execve", execv(cmd_args[0], cmd_args));
}
Esempio n. 2
0
int mount_fstab_main(int argc, char *argv[])
{
    int opt;

    static struct option long_options[] = {
        {"help", no_argument, 0, 'h'},
        {0, 0, 0, 0}
    };

    int long_index = 0;

    while ((opt = getopt_long(argc, argv, "h", long_options, &long_index)) != -1) {
        switch (opt) {
        case 'h':
            mount_fstab_usage(0);
            return EXIT_SUCCESS;

        default:
            mount_fstab_usage(1);
            return EXIT_FAILURE;
        }
    }

    // We only expect one argument
    if (argc - optind != 1) {
        mount_fstab_usage(1);
        return EXIT_FAILURE;
    }

    // Use the kernel log since logcat hasn't run yet
    util::log_set_logger(std::make_shared<util::KmsgLogger>());

    // Patch SELinux policy
    if (!patch_loaded_sepolicy()) {
        LOGE("Failed to patch loaded SELinux policy. Continuing anyway");
    } else {
        LOGV("SELinux policy patching completed");
    }

#if FORCE_SELINUX_PERMISSIVE
    int fd = open("/sys/fs/selinux/enforce", O_RDWR);
    if (fd > 0) {
        write(fd, "0", 1);
        close(fd);
    }
#endif

    if (!mount_fstab(argv[optind])) {
        LOGE("Failed to mount filesystems. Rebooting into recovery");
        reboot_directly("recovery");
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}
Esempio n. 3
0
int init_main(int argc, char *argv[])
{
    for (int i = 1; i < argc; ++i) {
        if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
            init_usage(true);
            return EXIT_SUCCESS;
        }
    }

    umask(0);

    mkdir("/dev", 0755);
    mkdir("/proc", 0755);
    mkdir("/sys", 0755);

    mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
    mkdir("/dev/pts", 0755);
    mkdir("/dev/socket", 0755);
    mount("devpts", "/dev/pts", "devpts", 0, nullptr);
    mount("proc", "/proc", "proc", 0, nullptr);
    mount("sysfs", "/sys", "sysfs", 0, nullptr);

    open_devnull_stdio();
    util::log_set_logger(std::make_shared<util::KmsgLogger>());
    if (klogctl(KLOG_CONSOLE_LEVEL, nullptr, 8) < 0) {
        LOGE("Failed to set loglevel: %s", strerror(errno));
    }

    LOGV("Booting up with version %s (%s)",
         get_mbtool_version(), get_git_version());

    // Start probing for devices
    device_init();

    std::string fstab = find_fstab();
    if (fstab.empty()) {
        LOGE("Failed to find a suitable fstab file");
        emergency_reboot();
        return EXIT_FAILURE;
    }

    mkdir("/system", 0755);
    mkdir("/cache", 0770);
    mkdir("/data", 0771);
    util::chown("/cache", "system", "cache", 0);
    util::chown("/data", "system", "system", 0);

    fix_arter97();

    // Mount fstab and write new redacted version
    if (!mount_fstab(fstab, true)) {
        LOGE("Failed to mount fstab");
        emergency_reboot();
        return EXIT_FAILURE;
    }

    LOGE("Successfully mounted fstab");

    fix_file_contexts();
    add_mbtool_services();
    strip_manual_mounts();

    struct stat sb;
    if (stat("/sepolicy", &sb) == 0) {
        if (!patch_sepolicy("/sepolicy", "/sepolicy")) {
            LOGW("Failed to patch /sepolicy");
            emergency_reboot();
            return EXIT_FAILURE;
        }
    }

    // Kill uevent thread and close uevent socket
    device_close();

    // Unmount partitions
    umount("/dev/pts");
    umount("/dev");
    umount("/proc");
    umount("/sys");
    // Do not remove these as Android 6.0 init's stage 1 no longer creates these
    // (platform/system/core commit a1f6a4b13921f61799be14a2544bdbf95958eae7)
    //rmdir("/dev");
    //rmdir("/proc");
    //rmdir("/sys");

    // Start real init
    unlink("/init");
    rename("/init.orig", "/init");

    LOGD("Launching real init ...");
    execlp("/init", "/init", nullptr);
    LOGE("Failed to exec real init: %s", strerror(errno));
    emergency_reboot();
    return EXIT_FAILURE;
}