libbinder: support BR_ONEWAY_SPAM_SUSPECT

This command tells userspace to dump current stack, which happened
when oneway spamming is detected in kernel. And also add an ioctl
command BINDER_ENABLE_ONEWAY_SPAM_DETECTION to enable/disable this
feature per-proc.

Bug: 181190340
Change-Id: I7afb1df46a4fbf59bc69b56649aa3ee779dfea5a
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 406bd54..6fb1227 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -90,6 +90,8 @@
     "BR_DEAD_BINDER",
     "BR_CLEAR_DEATH_NOTIFICATION_DONE",
     "BR_FAILED_REPLY",
+    "BR_FROZEN_REPLY",
+    "BR_ONEWAY_SPAM_SUSPECT",
     "BR_TRANSACTION_SEC_CTX",
 };
 
@@ -894,6 +896,11 @@
         }
 
         switch (cmd) {
+        case BR_ONEWAY_SPAM_SUSPECT:
+            ALOGE("Process seems to be sending too many oneway calls.");
+            CallStack::logStack("oneway spamming", CallStack::getCurrent().get(),
+                    ANDROID_LOG_ERROR);
+            [[fallthrough]];
         case BR_TRANSACTION_COMPLETE:
             if (!reply && !acquireResult) goto finish;
             break;
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index a8b2fb2..ca99042 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -43,6 +43,7 @@
 
 #define BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)
 #define DEFAULT_MAX_BINDER_THREADS 15
+#define DEFAULT_ENABLE_ONEWAY_SPAM_DETECTION 1
 
 #ifdef __ANDROID_VNDK__
 const char* kDefaultDriver = "/dev/vndbinder";
@@ -358,6 +359,15 @@
     return result;
 }
 
+status_t ProcessState::enableOnewaySpamDetection(bool enable) {
+    uint32_t enableDetection = enable ? 1 : 0;
+    if (ioctl(mDriverFD, BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enableDetection) == -1) {
+        ALOGE("Binder ioctl to enable oneway spam detection failed: %s", strerror(errno));
+        return -errno;
+    }
+    return NO_ERROR;
+}
+
 void ProcessState::giveThreadPoolName() {
     androidSetThreadName( makeBinderThreadName().string() );
 }
@@ -388,6 +398,11 @@
         if (result == -1) {
             ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
         }
+        uint32_t enable = DEFAULT_ENABLE_ONEWAY_SPAM_DETECTION;
+        result = ioctl(fd, BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enable);
+        if (result == -1) {
+            ALOGE("Binder ioctl to enable oneway spam detection failed: %s", strerror(errno));
+        }
     } else {
         ALOGW("Opening '%s' failed: %s\n", driver, strerror(errno));
     }
diff --git a/libs/binder/include/binder/ProcessState.h b/libs/binder/include/binder/ProcessState.h
index 0919648..b9db5d7 100644
--- a/libs/binder/include/binder/ProcessState.h
+++ b/libs/binder/include/binder/ProcessState.h
@@ -58,6 +58,7 @@
             void                spawnPooledThread(bool isMain);
             
             status_t            setThreadPoolMaxThreadCount(size_t maxThreads);
+            status_t            enableOnewaySpamDetection(bool enable);
             void                giveThreadPoolName();
 
             String8             getDriverName();
diff --git a/libs/binder/include/private/binder/binder_module.h b/libs/binder/include/private/binder/binder_module.h
index 1579199..151235c 100644
--- a/libs/binder/include/private/binder/binder_module.h
+++ b/libs/binder/include/private/binder/binder_module.h
@@ -32,10 +32,6 @@
 #include <sys/ioctl.h>
 #include <linux/android/binder.h>
 
-#ifdef __cplusplus
-namespace android {
-#endif
-
 #ifndef BR_FROZEN_REPLY
 // Temporary definition of BR_FROZEN_REPLY. For production
 // this will come from UAPI binder.h
@@ -88,8 +84,18 @@
 };
 #endif //BINDER_GET_FROZEN_INFO
 
-#ifdef __cplusplus
-}   // namespace android
-#endif
+#ifndef BR_ONEWAY_SPAM_SUSPECT
+// Temporary definition of BR_ONEWAY_SPAM_SUSPECT. For production
+// this will come from UAPI binder.h
+#define BR_ONEWAY_SPAM_SUSPECT _IO('r', 19)
+#endif //BR_ONEWAY_SPAM_SUSPECT
+
+#ifndef BINDER_ENABLE_ONEWAY_SPAM_DETECTION
+/*
+ * Temporary definitions for oneway spam detection support. For the final version
+ * these will be defined in the UAPI binder.h file from upstream kernel.
+ */
+#define BINDER_ENABLE_ONEWAY_SPAM_DETECTION _IOW('b', 16, __u32)
+#endif //BINDER_ENABLE_ONEWAY_SPAM_DETECTION
 
 #endif // _BINDER_MODULE_H_