libhwbinder: support BR_ONEWAY_SPAM_SUSPECT am: d1388da3a1 am: be5d1f4dd4 am: 4fffe0825a

Original change: https://android-review.googlesource.com/c/platform/system/libhwbinder/+/1676704

Change-Id: I2b33523205aa7775f1660c2d491e788ad684d2a8
diff --git a/IPCThreadState.cpp b/IPCThreadState.cpp
index e7fbc53..aa050fc 100644
--- a/IPCThreadState.cpp
+++ b/IPCThreadState.cpp
@@ -88,6 +88,8 @@
     "BR_DEAD_BINDER",
     "BR_CLEAR_DEATH_NOTIFICATION_DONE",
     "BR_FAILED_REPLY",
+    "BR_FROZEN_REPLY",
+    "BR_ONEWAY_SPAM_SUSPECT",
     "BR_TRANSACTION_SEC_CTX",
 };
 
@@ -802,6 +804,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/ProcessState.cpp b/ProcessState.cpp
index 1d35e7e..2e96d0f 100644
--- a/ProcessState.cpp
+++ b/ProcessState.cpp
@@ -40,6 +40,7 @@
 
 #define DEFAULT_BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)
 #define DEFAULT_MAX_BINDER_THREADS 0
+#define DEFAULT_ENABLE_ONEWAY_SPAM_DETECTION 1
 
 // -------------------------------------------------------------------------
 
@@ -343,6 +344,15 @@
     return NO_ERROR;
 }
 
+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;
+}
+
 size_t ProcessState::getMaxThreads() {
     return mMaxThreads;
 }
@@ -372,6 +382,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 '/dev/hwbinder' failed: %s\n", strerror(errno));
     }
diff --git a/binder_kernel.h b/binder_kernel.h
index 64103bd..2695f51 100644
--- a/binder_kernel.h
+++ b/binder_kernel.h
@@ -22,6 +22,21 @@
 #define __packed __attribute__((__packed__))
 #endif
 
+#include <sys/ioctl.h>
 #include <linux/android/binder.h>
 
+#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 // ANDROID_HARDWARE_BINDER_KERNEL_H
diff --git a/include/hwbinder/ProcessState.h b/include/hwbinder/ProcessState.h
index 00450f1..56ac846 100644
--- a/include/hwbinder/ProcessState.h
+++ b/include/hwbinder/ProcessState.h
@@ -58,6 +58,7 @@
             void                spawnPooledThread(bool isMain);
 
             status_t            setThreadPoolConfiguration(size_t maxThreads, bool callerJoinsPool);
+            status_t            enableOnewaySpamDetection(bool enable);
             size_t              getMaxThreads();
             void                giveThreadPoolName();