init: add "+passcred" for socket to set SO_PASSCRED

In the init scripts for socket, the type can have a suffix of
"+passcred" to request that the socket be bound to report SO_PASSCRED
credentials as part of socket transactions.

Test: gTest logd-unit-tests --gtest_filter=logd.statistics right after boot
      (fails without logd.rc change)
Bug: 37985222
Change-Id: Ie5b50e99fb92fa9bec9a32463a0e6df26a968bfd
diff --git a/init/util.cpp b/init/util.cpp
index e7f724b..5afe285 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -78,13 +78,13 @@
 }
 
 /*
- * create_socket - creates a Unix domain socket in ANDROID_SOCKET_DIR
+ * CreateSocket - creates a Unix domain socket in ANDROID_SOCKET_DIR
  * ("/dev/socket") as dictated in init.rc. This socket is inherited by the
  * daemon. We communicate the file descriptor's value via the environment
  * variable ANDROID_SOCKET_ENV_PREFIX<name> ("ANDROID_SOCKET_foo").
  */
-int create_socket(const char* name, int type, mode_t perm, uid_t uid, gid_t gid,
-                  const char* socketcon, selabel_handle* sehandle) {
+int CreateSocket(const char* name, int type, bool passcred, mode_t perm, uid_t uid, gid_t gid,
+                 const char* socketcon, selabel_handle* sehandle) {
     if (socketcon) {
         if (setsockcreatecon(socketcon) == -1) {
             PLOG(ERROR) << "setsockcreatecon(\"" << socketcon << "\") failed";
@@ -118,6 +118,14 @@
         }
     }
 
+    if (passcred) {
+        int on = 1;
+        if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on))) {
+            PLOG(ERROR) << "Failed to set SO_PASSCRED '" << name << "'";
+            return -1;
+        }
+    }
+
     int ret = bind(fd, (struct sockaddr *) &addr, sizeof (addr));
     int savederrno = errno;