Only allow extra_guardrails for domains that can connect to heapprofd.

Always load perfetto_hprof plugin for system server, as it does not have
a manifest. The android_mallopt call marking it as profileable comes too
late for plugin initialization, so we have to hardcode here.

Test: flash user device
      allow systemui to use central heapprofd
      make system_server perfetto producer
      profile systemui with extra guardrails -> success
      profile sys_srv without extra guardrails -> success
      profile sys_srv with extra guardrails -> rejected
Bug: 151140716
Change-Id: Icb8b70139eabca19838f0b122cc62af6b7c5a6ab
diff --git a/perfetto_hprof/perfetto_hprof.cc b/perfetto_hprof/perfetto_hprof.cc
index 8ee6c07..33fc73e 100644
--- a/perfetto_hprof/perfetto_hprof.cc
+++ b/perfetto_hprof/perfetto_hprof.cc
@@ -23,8 +23,10 @@
 #include <inttypes.h>
 #include <sched.h>
 #include <signal.h>
+#include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <sys/un.h>
 #include <sys/wait.h>
 #include <thread>
 #include <time.h>
@@ -144,6 +146,20 @@
   return false;
 }
 
+bool CanConnectToSocket(const char* name) {
+  struct sockaddr_un addr = {};
+  addr.sun_family = AF_UNIX;
+  strncpy(addr.sun_path, name, sizeof(addr.sun_path) - 1);
+  int fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+  if (fd == -1) {
+    PLOG(ERROR) << "failed to create socket";
+    return false;
+  }
+  bool connected = connect(fd, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)) == 0;
+  close(fd);
+  return connected;
+}
+
 constexpr size_t kMaxCmdlineSize = 512;
 
 class JavaHprofDataSource : public perfetto::DataSource<JavaHprofDataSource> {
@@ -156,6 +172,12 @@
         new perfetto::protos::pbzero::JavaHprofConfig::Decoder(
           args.config->java_hprof_config_raw()));
 
+    if (args.config->enable_extra_guardrails() && !CanConnectToSocket("/dev/socket/heapprofd")) {
+      LOG(ERROR) << "rejecting extra guardrails";
+      enabled_ = false;
+      return;
+    }
+
     dump_smaps_ = cfg->dump_smaps();
 
     uint64_t self_pid = static_cast<uint64_t>(getpid());
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index b62cd11..d7682bb 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1059,7 +1059,8 @@
   StartSignalCatcher();
 
   ScopedObjectAccess soa(Thread::Current());
-  if (Dbg::IsJdwpAllowed() || IsProfileableFromShell() || IsJavaDebuggable()) {
+  if (Dbg::IsJdwpAllowed() || IsProfileableFromShell() || IsJavaDebuggable() ||
+      Runtime::Current()->IsSystemServer()) {
     std::string err;
     ScopedTrace tr("perfetto_hprof init.");
     ScopedThreadSuspension sts(Thread::Current(), ThreadState::kNative);