Fix deadlock caused by two-threaded property controls

Two threaded property controls were introduced in ag/21063815 to prevent
DOS for power controls. However, this causes deadlocks, so limit the
second thread to just sys.powerctl messages.

Bug: 273785601
Test: Boots, power messages work
Ignore-AOSP-First: Security fix
Change-Id: Ie27dc3b0cd9e2d28e94f2ad398c55ee27bc35835
This commit is contained in:
Paul Lawrence 2023-03-24 14:31:57 -07:00
parent bfd626e78f
commit 606afc7b74

View file

@ -117,7 +117,6 @@ static bool accept_messages = false;
static std::mutex accept_messages_lock;
static std::thread property_service_thread;
static std::thread property_service_for_system_thread;
static std::mutex set_property_lock;
static std::unique_ptr<PersistWriteThread> persist_write_thread;
@ -395,32 +394,37 @@ static std::optional<uint32_t> PropertySet(const std::string& name, const std::s
return {PROP_ERROR_INVALID_VALUE};
}
auto lock = std::lock_guard{set_property_lock};
prop_info* pi = (prop_info*)__system_property_find(name.c_str());
if (pi != nullptr) {
// ro.* properties are actually "write-once".
if (StartsWith(name, "ro.")) {
*error = "Read-only property was already set";
return {PROP_ERROR_READ_ONLY_PROPERTY};
}
__system_property_update(pi, value.c_str(), valuelen);
if (name == "sys.powerctl") {
// No action here - NotifyPropertyChange will trigger the appropriate action, and since this
// can come to the second thread, we mustn't call out to the __system_property_* functions
// which support multiple readers but only one mutator.
} else {
int rc = __system_property_add(name.c_str(), name.size(), value.c_str(), valuelen);
if (rc < 0) {
*error = "__system_property_add failed";
return {PROP_ERROR_SET_FAILED};
}
}
prop_info* pi = (prop_info*)__system_property_find(name.c_str());
if (pi != nullptr) {
// ro.* properties are actually "write-once".
if (StartsWith(name, "ro.")) {
*error = "Read-only property was already set";
return {PROP_ERROR_READ_ONLY_PROPERTY};
}
// Don't write properties to disk until after we have read all default
// properties to prevent them from being overwritten by default values.
if (socket && persistent_properties_loaded && StartsWith(name, "persist.")) {
if (persist_write_thread) {
persist_write_thread->Write(name, value, std::move(*socket));
return {};
__system_property_update(pi, value.c_str(), valuelen);
} else {
int rc = __system_property_add(name.c_str(), name.size(), value.c_str(), valuelen);
if (rc < 0) {
*error = "__system_property_add failed";
return {PROP_ERROR_SET_FAILED};
}
}
// Don't write properties to disk until after we have read all default
// properties to prevent them from being overwritten by default values.
if (socket && persistent_properties_loaded && StartsWith(name, "persist.")) {
if (persist_write_thread) {
persist_write_thread->Write(name, value, std::move(*socket));
return {};
}
WritePersistentProperty(name, value);
}
WritePersistentProperty(name, value);
}
NotifyPropertyChange(name, value);