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; }
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; }
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; }
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; }