summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHang Lu <quic_hangl@quicinc.com>2021-03-24 14:30:06 +0800
committerHang Lu <quic_hangl@quicinc.com>2021-04-17 17:05:22 +0800
commitd1388da3a14d78d57f6bd94bea647f7f09869310 (patch)
tree62b94194b1d901948b2db5abb44b60bf9adceac5
parentc2f9903179cf15e6d89f13d7d9fbe0ee197630ce (diff)
downloadlibhwbinder-d1388da3a14d78d57f6bd94bea647f7f09869310.tar.gz
libhwbinder: 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: I005a0a394a43ed4ee34b4ad7a963557bd15a1f6b
-rw-r--r--IPCThreadState.cpp7
-rw-r--r--ProcessState.cpp15
-rw-r--r--binder_kernel.h15
-rw-r--r--include/hwbinder/ProcessState.h1
4 files changed, 38 insertions, 0 deletions
diff --git a/IPCThreadState.cpp b/IPCThreadState.cpp
index e7fbc53..aa050fc 100644
--- a/IPCThreadState.cpp
+++ b/IPCThreadState.cpp
@@ -88,6 +88,8 @@ static const char *kReturnStrings[] = {
"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 @@ status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
}
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 @@ status_t ProcessState::setThreadPoolConfiguration(size_t maxThreads, bool caller
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 @@ static int open_driver()
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 @@ public:
void spawnPooledThread(bool isMain);
status_t setThreadPoolConfiguration(size_t maxThreads, bool callerJoinsPool);
+ status_t enableOnewaySpamDetection(bool enable);
size_t getMaxThreads();
void giveThreadPoolName();