diff --git a/init/property_service.cpp b/init/property_service.cpp index 655b8deef..842b2e5b7 100644 --- a/init/property_service.cpp +++ b/init/property_service.cpp @@ -47,6 +47,7 @@ #include #include +#include #include #include #include @@ -85,6 +86,7 @@ using android::properties::BuildTrie; using android::properties::ParsePropertyInfoFile; using android::properties::PropertyInfoAreaFile; using android::properties::PropertyInfoEntry; +using android::sysprop::InitProperties::is_userspace_reboot_supported; namespace android { namespace init { @@ -492,6 +494,10 @@ uint32_t HandlePropertySet(const std::string& name, const std::string& value, if (!value.empty()) { DebugRebootLogging(); } + if (value == "reboot,userspace" && !is_userspace_reboot_supported().value_or(false)) { + *error = "Userspace reboot is not supported by this device"; + return PROP_ERROR_INVALID_VALUE; + } } // If a process other than init is writing a non-empty value, it means that process is diff --git a/init/property_service_test.cpp b/init/property_service_test.cpp index 0f4cd0d1f..c6dcfa257 100644 --- a/init/property_service_test.cpp +++ b/init/property_service_test.cpp @@ -22,8 +22,10 @@ #include #include +#include #include +using android::base::GetProperty; using android::base::SetProperty; namespace android { @@ -74,5 +76,19 @@ TEST(property_service, non_utf8_value) { EXPECT_TRUE(SetProperty("property_service_utf8_test", "\xF0\x90\x80\x80")); } +TEST(property_service, userspace_reboot_not_supported) { + if (getuid() != 0) { + GTEST_SKIP() << "Skipping test, must be run as root."; + return; + } + const std::string original_value = GetProperty("init.userspace_reboot.is_supported", ""); + auto guard = android::base::make_scope_guard([&original_value]() { + SetProperty("init.userspace_reboot.is_supported", original_value); + }); + + ASSERT_TRUE(SetProperty("init.userspace_reboot.is_supported", "false")); + EXPECT_FALSE(SetProperty("sys.powerctl", "reboot,userspace")); +} + } // namespace init } // namespace android