Loading init/builtins.cpp +46 −23 Original line number Diff line number Diff line Loading @@ -80,6 +80,7 @@ using namespace std::literals::string_literals; using android::base::Basename; using android::base::StringPrintf; using android::base::unique_fd; using android::fs_mgr::Fstab; using android::fs_mgr::ReadFstabFromFile; Loading Loading @@ -1062,17 +1063,45 @@ static bool is_file_crypto() { return android::base::GetProperty("ro.crypto.type", "") == "file"; } static Result<void> ExecWithRebootOnFailure(const std::string& reboot_reason, const BuiltinArguments& args) { auto service = Service::MakeTemporaryOneshotService(args.args); static Result<void> ExecWithFunctionOnFailure(const std::vector<std::string>& args, std::function<void(const std::string&)> function) { auto service = Service::MakeTemporaryOneshotService(args); if (!service) { return Error() << "Could not create exec service: " << service.error(); function("MakeTemporaryOneshotService failed: " + service.error().message()); } (*service)->AddReapCallback([reboot_reason](const siginfo_t& siginfo) { (*service)->AddReapCallback([function](const siginfo_t& siginfo) { if (siginfo.si_code != CLD_EXITED || siginfo.si_status != 0) { function(StringPrintf("Exec service failed, status %d", siginfo.si_status)); } }); if (auto result = (*service)->ExecStart(); !result) { function("ExecStart failed: " + result.error().message()); } ServiceList::GetInstance().AddService(std::move(*service)); return {}; } static Result<void> do_exec_reboot_on_failure(const BuiltinArguments& args) { auto reboot_reason = args[1]; auto reboot = [reboot_reason](const std::string& message) { property_set(LAST_REBOOT_REASON_PROPERTY, reboot_reason); sync(); LOG(FATAL) << message << ": rebooting into bootloader, reason: " << reboot_reason; }; std::vector<std::string> remaining_args(args.begin() + 1, args.end()); remaining_args[0] = args[0]; return ExecWithFunctionOnFailure(remaining_args, reboot); } static Result<void> ExecVdcRebootOnFailure(const std::string& vdc_arg) { auto reboot_reason = vdc_arg + "_failed"; auto reboot = [reboot_reason](const std::string& message) { // TODO (b/122850122): support this in gsi if (fscrypt_is_native() && !android::gsi::IsGsiRunning()) { LOG(ERROR) << "Rebooting into recovery, reason: " << reboot_reason; LOG(ERROR) << message << ": Rebooting into recovery, reason: " << reboot_reason; if (auto result = reboot_into_recovery( {"--prompt_and_wipe_data", "--reason="s + reboot_reason}); !result) { Loading @@ -1081,13 +1110,10 @@ static Result<void> ExecWithRebootOnFailure(const std::string& reboot_reason, } else { LOG(ERROR) << "Failure (reboot suppressed): " << reboot_reason; } } }); if (auto result = (*service)->ExecStart(); !result) { return Error() << "Could not start exec service: " << result.error(); } ServiceList::GetInstance().AddService(std::move(*service)); return {}; }; std::vector<std::string> args = {"exec", "/system/bin/vdc", "--wait", "cryptfs", vdc_arg}; return ExecWithFunctionOnFailure(args, reboot); } static Result<void> do_installkey(const BuiltinArguments& args) { Loading @@ -1097,15 +1123,11 @@ static Result<void> do_installkey(const BuiltinArguments& args) { if (!make_dir(unencrypted_dir, 0700) && errno != EEXIST) { return ErrnoError() << "Failed to create " << unencrypted_dir; } return ExecWithRebootOnFailure( "enablefilecrypto_failed", {{"exec", "/system/bin/vdc", "--wait", "cryptfs", "enablefilecrypto"}, args.context}); return ExecVdcRebootOnFailure("enablefilecrypto"); } static Result<void> do_init_user0(const BuiltinArguments& args) { return ExecWithRebootOnFailure( "init_user0_failed", {{"exec", "/system/bin/vdc", "--wait", "cryptfs", "init_user0"}, args.context}); return ExecVdcRebootOnFailure("init_user0"); } static Result<void> do_mark_post_data(const BuiltinArguments& args) { Loading Loading @@ -1180,6 +1202,7 @@ const BuiltinFunctionMap& GetBuiltinFunctionMap() { {"enable", {1, 1, {false, do_enable}}}, {"exec", {1, kMax, {false, do_exec}}}, {"exec_background", {1, kMax, {false, do_exec_background}}}, {"exec_reboot_on_failure", {2, kMax, {false, do_exec_reboot_on_failure}}}, {"exec_start", {1, 1, {false, do_exec_start}}}, {"export", {2, 2, {false, do_export}}}, {"hostname", {1, 1, {true, do_hostname}}}, Loading init/check_builtins.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,15 @@ Result<void> check_exec_background(const BuiltinArguments& args) { return check_exec(std::move(args)); } Result<void> check_exec_reboot_on_failure(const BuiltinArguments& args) { BuiltinArguments remaining_args(args.context); remaining_args.args = std::vector<std::string>(args.begin() + 1, args.end()); remaining_args.args[0] = args[0]; return check_exec(remaining_args); } Result<void> check_interface_restart(const BuiltinArguments& args) { if (auto result = IsKnownInterface(args[1]); !result) { return result.error(); Loading init/check_builtins.h +1 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ namespace init { Result<void> check_chown(const BuiltinArguments& args); Result<void> check_exec(const BuiltinArguments& args); Result<void> check_exec_background(const BuiltinArguments& args); Result<void> check_exec_reboot_on_failure(const BuiltinArguments& args); Result<void> check_interface_restart(const BuiltinArguments& args); Result<void> check_interface_start(const BuiltinArguments& args); Result<void> check_interface_stop(const BuiltinArguments& args); Loading Loading
init/builtins.cpp +46 −23 Original line number Diff line number Diff line Loading @@ -80,6 +80,7 @@ using namespace std::literals::string_literals; using android::base::Basename; using android::base::StringPrintf; using android::base::unique_fd; using android::fs_mgr::Fstab; using android::fs_mgr::ReadFstabFromFile; Loading Loading @@ -1062,17 +1063,45 @@ static bool is_file_crypto() { return android::base::GetProperty("ro.crypto.type", "") == "file"; } static Result<void> ExecWithRebootOnFailure(const std::string& reboot_reason, const BuiltinArguments& args) { auto service = Service::MakeTemporaryOneshotService(args.args); static Result<void> ExecWithFunctionOnFailure(const std::vector<std::string>& args, std::function<void(const std::string&)> function) { auto service = Service::MakeTemporaryOneshotService(args); if (!service) { return Error() << "Could not create exec service: " << service.error(); function("MakeTemporaryOneshotService failed: " + service.error().message()); } (*service)->AddReapCallback([reboot_reason](const siginfo_t& siginfo) { (*service)->AddReapCallback([function](const siginfo_t& siginfo) { if (siginfo.si_code != CLD_EXITED || siginfo.si_status != 0) { function(StringPrintf("Exec service failed, status %d", siginfo.si_status)); } }); if (auto result = (*service)->ExecStart(); !result) { function("ExecStart failed: " + result.error().message()); } ServiceList::GetInstance().AddService(std::move(*service)); return {}; } static Result<void> do_exec_reboot_on_failure(const BuiltinArguments& args) { auto reboot_reason = args[1]; auto reboot = [reboot_reason](const std::string& message) { property_set(LAST_REBOOT_REASON_PROPERTY, reboot_reason); sync(); LOG(FATAL) << message << ": rebooting into bootloader, reason: " << reboot_reason; }; std::vector<std::string> remaining_args(args.begin() + 1, args.end()); remaining_args[0] = args[0]; return ExecWithFunctionOnFailure(remaining_args, reboot); } static Result<void> ExecVdcRebootOnFailure(const std::string& vdc_arg) { auto reboot_reason = vdc_arg + "_failed"; auto reboot = [reboot_reason](const std::string& message) { // TODO (b/122850122): support this in gsi if (fscrypt_is_native() && !android::gsi::IsGsiRunning()) { LOG(ERROR) << "Rebooting into recovery, reason: " << reboot_reason; LOG(ERROR) << message << ": Rebooting into recovery, reason: " << reboot_reason; if (auto result = reboot_into_recovery( {"--prompt_and_wipe_data", "--reason="s + reboot_reason}); !result) { Loading @@ -1081,13 +1110,10 @@ static Result<void> ExecWithRebootOnFailure(const std::string& reboot_reason, } else { LOG(ERROR) << "Failure (reboot suppressed): " << reboot_reason; } } }); if (auto result = (*service)->ExecStart(); !result) { return Error() << "Could not start exec service: " << result.error(); } ServiceList::GetInstance().AddService(std::move(*service)); return {}; }; std::vector<std::string> args = {"exec", "/system/bin/vdc", "--wait", "cryptfs", vdc_arg}; return ExecWithFunctionOnFailure(args, reboot); } static Result<void> do_installkey(const BuiltinArguments& args) { Loading @@ -1097,15 +1123,11 @@ static Result<void> do_installkey(const BuiltinArguments& args) { if (!make_dir(unencrypted_dir, 0700) && errno != EEXIST) { return ErrnoError() << "Failed to create " << unencrypted_dir; } return ExecWithRebootOnFailure( "enablefilecrypto_failed", {{"exec", "/system/bin/vdc", "--wait", "cryptfs", "enablefilecrypto"}, args.context}); return ExecVdcRebootOnFailure("enablefilecrypto"); } static Result<void> do_init_user0(const BuiltinArguments& args) { return ExecWithRebootOnFailure( "init_user0_failed", {{"exec", "/system/bin/vdc", "--wait", "cryptfs", "init_user0"}, args.context}); return ExecVdcRebootOnFailure("init_user0"); } static Result<void> do_mark_post_data(const BuiltinArguments& args) { Loading Loading @@ -1180,6 +1202,7 @@ const BuiltinFunctionMap& GetBuiltinFunctionMap() { {"enable", {1, 1, {false, do_enable}}}, {"exec", {1, kMax, {false, do_exec}}}, {"exec_background", {1, kMax, {false, do_exec_background}}}, {"exec_reboot_on_failure", {2, kMax, {false, do_exec_reboot_on_failure}}}, {"exec_start", {1, 1, {false, do_exec_start}}}, {"export", {2, 2, {false, do_export}}}, {"hostname", {1, 1, {true, do_hostname}}}, Loading
init/check_builtins.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,15 @@ Result<void> check_exec_background(const BuiltinArguments& args) { return check_exec(std::move(args)); } Result<void> check_exec_reboot_on_failure(const BuiltinArguments& args) { BuiltinArguments remaining_args(args.context); remaining_args.args = std::vector<std::string>(args.begin() + 1, args.end()); remaining_args.args[0] = args[0]; return check_exec(remaining_args); } Result<void> check_interface_restart(const BuiltinArguments& args) { if (auto result = IsKnownInterface(args[1]); !result) { return result.error(); Loading
init/check_builtins.h +1 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ namespace init { Result<void> check_chown(const BuiltinArguments& args); Result<void> check_exec(const BuiltinArguments& args); Result<void> check_exec_background(const BuiltinArguments& args); Result<void> check_exec_reboot_on_failure(const BuiltinArguments& args); Result<void> check_interface_restart(const BuiltinArguments& args); Result<void> check_interface_start(const BuiltinArguments& args); Result<void> check_interface_stop(const BuiltinArguments& args); Loading