예제 #1
0
Installer::ProceedState RecoveryInstaller::on_initialize()
{
    struct stat sb;
    if (stat("/sys/fs/selinux", &sb) == 0) {
        if (!patch_sepolicy()) {
            LOGE("Failed to patch sepolicy. Trying to disable SELinux");
            int fd = open(SELINUX_ENFORCE_FILE, O_WRONLY);
            if (fd >= 0) {
                write(fd, "0", 1);
                close(fd);
            } else {
                LOGE("Failed to set SELinux to permissive mode");
                display_msg("Could not patch or disable SELinux");
            }
        }
    }

    return ProceedState::Continue;
}
예제 #2
0
int rom_installer_main(int argc, char *argv[])
{
    // Make stdout unbuffered
    setvbuf(stdout, nullptr, _IONBF, 0);

    std::string rom_id;
    std::string zip_file;

    int opt;

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

    int long_index = 0;

    while ((opt = getopt_long(argc, argv, "r:h", long_options, &long_index)) != -1) {
        switch (opt) {
        case 'r':
            rom_id = optarg;
            break;

        case 'h':
            rom_installer_usage(false);
            return EXIT_SUCCESS;

        default:
            rom_installer_usage(true);
            return EXIT_FAILURE;
        }
    }

    if (argc - optind != 1) {
        rom_installer_usage(true);
        return EXIT_FAILURE;
    }

    zip_file = argv[optind];

    if (rom_id.empty()) {
        fprintf(stderr, "-r/--romid must be specified\n");
        return EXIT_FAILURE;
    }

    if (zip_file.empty()) {
        fprintf(stderr, "Invalid zip file path\n");
        return EXIT_FAILURE;
    }


    // Translate paths
    char *emu_source_path = getenv("EMULATED_STORAGE_SOURCE");
    char *emu_target_path = getenv("EMULATED_STORAGE_TARGET");
    if (emu_source_path && emu_target_path) {
        if (util::starts_with(zip_file, emu_target_path)) {
            printf("Zip path uses EMULATED_STORAGE_TARGET\n");
            zip_file.erase(0, strlen(emu_target_path));
            zip_file.insert(0, emu_source_path);
        }
    }


    // Make sure install type is valid
    if (!Roms::is_valid(rom_id)) {
        fprintf(stderr, "Invalid ROM ID: %s\n", rom_id.c_str());
        return EXIT_FAILURE;
    }

    auto rom = Roms::get_current_rom();
    if (!rom) {
        fprintf(stderr, "Could not determine current ROM\n");
        return EXIT_FAILURE;
    }

    if (rom->id == rom_id) {
        fprintf(stderr, "Can't install over current ROM (%s)\n",
                rom_id.c_str());
        return EXIT_FAILURE;
    }


    if (geteuid() != 0) {
        fprintf(stderr, "rom-installer must be run as root\n");
        return EXIT_FAILURE;
    }


    // Since many stock ROMs, most notably TouchWiz, don't allow setting SELinux
    // to be globally permissive, we'll do the next best thing: modify the
    // policy to make every type permissive.

    bool selinux_supported = true;
    bool backup_successful = true;

    struct stat sb;
    if (stat("/sys/fs/selinux", &sb) < 0) {
        printf("SELinux not supported. No need to modify policy\n");
        selinux_supported = false;
    }

    if (selinux_supported) {
        backup_successful = backup_sepolicy(sepolicy_bak_path);

        printf("Patching SELinux policy to make all types permissive\n");
        if (!patch_sepolicy()) {
            fprintf(stderr, "Failed to patch current SELinux policy\n");
        }
    }

    auto restore_selinux = util::finally([&] {
        if (selinux_supported && backup_successful) {
            printf("Restoring backup SELinux policy\n");
            if (!restore_sepolicy(sepolicy_bak_path)) {
                fprintf(stderr, "Failed to restore SELinux policy\n");
            }
        }
    });


    autoclose::file fp(autoclose::fopen(MULTIBOOT_LOG_INSTALLER, "wb"));
    if (!fp) {
        fprintf(stderr, "Failed to open %s: %s\n",
                MULTIBOOT_LOG_INSTALLER, strerror(errno));
        return EXIT_FAILURE;
    }

    fix_multiboot_permissions();

    // mbtool logging
    util::log_set_logger(std::make_shared<util::StdioLogger>(fp.get(), false));

    // libmbp logging
    mbp::setLogCallback(mbp_log_cb);

    // Start installing!
    RomInstaller ri(zip_file, rom_id, fp.get());
    return ri.start_installation() ? EXIT_SUCCESS : EXIT_FAILURE;
}
예제 #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;
}
예제 #4
0
int sepolpatch_main(int argc, char *argv[])
{
    int opt;
    int loaded_flag = 0;
    const char *source_file = nullptr;
    const char *target_file = nullptr;

    static struct option long_options[] = {
        {"loaded", no_argument,       0, 'l'},
        {"source", required_argument, 0, 's'},
        {"target", required_argument, 0, 't'},
        {"help",   no_argument,       0, 'h'},
        {0, 0, 0, 0}
    };

    int long_index = 0;

    while ((opt = getopt_long(argc, argv, "ls:t:h", long_options, &long_index)) != -1) {
        switch (opt) {
        case 'l':
            loaded_flag = 1;
            break;

        case 's':
            source_file = optarg;
            break;

        case 't':
            target_file = optarg;
            break;

        case 'h':
            sepolpatch_usage(0);
            return EXIT_SUCCESS;

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

    // There should be no other arguments
    if (argc - optind != 0) {
        sepolpatch_usage(1);
        return EXIT_FAILURE;
    }

    if (!loaded_flag && !source_file && !target_file) {
        sepolpatch_usage(1);
        return EXIT_FAILURE;
    }

    if (loaded_flag) {
        if (source_file || target_file) {
            fprintf(stderr, "'--source' and '--target' cannot be used with '--loaded'\n");
            return EXIT_FAILURE;
        }

        return patch_loaded_sepolicy() == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
    }

    if (!source_file) {
        source_file = SELINUX_POLICY_FILE;
    }
    if (!target_file) {
        target_file = SELINUX_LOAD_FILE;
    }

    return patch_sepolicy(source_file, target_file) ? EXIT_SUCCESS : EXIT_FAILURE;
}