libbinder: stability check moved to trans time
Before: stability check done when binder is read from a parcel
After: stability check done when binder is transacted on
Why this change is being made/benefits:
- vendor binders can be used as tokens in system context
- pingBinder/interfaceChain/etc.. can be done on vendor binders in a
system context, so code can generically operate on binders. This is
particularly useful for service manager and dumpstate, which previously
I was going to special-case
- policy on which binders go where is entirely reliant on SELinux
whereas before there were additional runtime restrictions
Cons to this change:
- allowed binders must be determined by context. BpBinder now checks
stability based on kLocalStability. More work would need to be done to
get this working with APEX.
Bug: 136027762
Test: binderStabilityTest
Change-Id: Iff026e81a130dbb8885ca82ec24e69a5768847eb
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index 57440d5..74ffde2 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -21,6 +21,7 @@
#include <binder/IPCThreadState.h>
#include <binder/IResultReceiver.h>
+#include <binder/Stability.h>
#include <cutils/compiler.h>
#include <utils/Log.h>
@@ -213,14 +214,21 @@
{
// Once a binder has died, it will never come back to life.
if (mAlive) {
+ // user transactions require a given stability level
+ if (code >= FIRST_CALL_TRANSACTION && code <= LAST_CALL_TRANSACTION) {
+ using android::internal::Stability;
+
+ auto stability = Stability::get(this);
+
+ if (CC_UNLIKELY(!Stability::check(stability, Stability::kLocalStability))) {
+ return BAD_TYPE;
+ }
+ }
+
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
- if (reply != nullptr) {
- reply->setTransactingBinder(this);
- }
-
return status;
}