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: I6d2bd566781ed712b41eb711360471fc0d030e54
diff --git a/libc/bionic/system_property_set.cpp b/libc/bionic/system_property_set.cpp
index bde0c10..845ff27 100644
--- a/libc/bionic/system_property_set.cpp
+++ b/libc/bionic/system_property_set.cpp
@@ -55,16 +55,24 @@
 
 class PropertyServiceConnection {
  public:
-  PropertyServiceConnection() : last_error_(0) {
+  PropertyServiceConnection(const char* name) : last_error_(0) {
     socket_.reset(::socket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0));
     if (socket_.get() == -1) {
       last_error_ = errno;
       return;
     }
 
-    const char* socket = access(property_service_for_system_socket, W_OK) == 0
-                             ? property_service_for_system_socket
-                             : property_service_socket;
+    // If we're trying to set "sys.powerctl" from a privileged process, use the special
+    // socket. Because this socket is only accessible to privileged processes, it can't
+    // be DoSed directly by malicious apps. (The shell user should be able to reboot,
+    // though, so we don't just always use the special socket for "sys.powerctl".)
+    // See b/262237198 for context
+    const char* socket = property_service_socket;
+    if (strcmp(name, "sys.powerctl") == 0 &&
+        access(property_service_for_system_socket, W_OK) == 0) {
+      socket = property_service_for_system_socket;
+    }
+
     const size_t namelen = strlen(socket);
     sockaddr_un addr;
     memset(&addr, 0, sizeof(addr));
@@ -181,7 +189,7 @@
 };
 
 static int send_prop_msg(const prop_msg* msg) {
-  PropertyServiceConnection connection;
+  PropertyServiceConnection connection(msg->name);
   if (!connection.IsValid()) {
     return connection.GetLastError();
   }
@@ -274,7 +282,7 @@
     // New protocol only allows long values for ro. properties only.
     if (strlen(value) >= PROP_VALUE_MAX && strncmp(key, "ro.", 3) != 0) return -1;
     // Use proper protocol
-    PropertyServiceConnection connection;
+    PropertyServiceConnection connection(key);
     if (!connection.IsValid()) {
       errno = connection.GetLastError();
       async_safe_format_log(