summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@android.com>2010-08-30 16:01:16 -0700
committerBrad Fitzpatrick <bradfitz@android.com>2010-08-31 13:16:49 -0700
commit0234376503ce421c4b871d5d811c541f5094301a (patch)
tree6f4686cb9bdc0d19f8c4b541c57ad5b10496588a
parent6aacad66eba2b51251f7e2dfb8c005b5242326ca (diff)
downloadframeworks_base-0234376503ce421c4b871d5d811c541f5094301a.zip
frameworks_base-0234376503ce421c4b871d5d811c541f5094301a.tar.gz
frameworks_base-0234376503ce421c4b871d5d811c541f5094301a.tar.bz2
Don't propagate StrictMode over one-way Binder calls.
This was causing stack stitching problems where a one-way call with violations followed by a two-way call without violations was getting the previous one-way call's violation stack stitched on to the second caller's stack. The solution is a little more indirect than I would've liked (preserving the binder's onTransact flags until enforceInterface) but was seemingly necessary to work without changing the AIDL compiler. It should also be sufficiently cheap, since no new calls to thread-local IPCThreadState lookups were required. The additional work is just same-thread getter/setters on the existing IPCThreadState. Change-Id: I4b6db1d445c56e868e6d0d7be3ba6849f4ef23ae
-rw-r--r--core/jni/android_util_Binder.cpp1
-rw-r--r--include/binder/IPCThreadState.h6
-rw-r--r--libs/binder/IPCThreadState.cpp22
-rw-r--r--libs/binder/Parcel.cpp11
4 files changed, 33 insertions, 7 deletions
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 5c4e4fd..7a53874 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -270,6 +270,7 @@ protected:
IPCThreadState* thread_state = IPCThreadState::self();
const int strict_policy_before = thread_state->getStrictModePolicy();
+ thread_state->setLastTransactionBinderFlags(flags);
//printf("Transact from %p to Java code sending: ", this);
//data.print();
diff --git a/include/binder/IPCThreadState.h b/include/binder/IPCThreadState.h
index 04e24d2..b54718f 100644
--- a/include/binder/IPCThreadState.h
+++ b/include/binder/IPCThreadState.h
@@ -43,7 +43,10 @@ public:
void setStrictModePolicy(int32_t policy);
int32_t getStrictModePolicy() const;
-
+
+ void setLastTransactionBinderFlags(int32_t flags);
+ int32_t getLastTransactionBinderFlags() const;
+
int64_t clearCallingIdentity();
void restoreCallingIdentity(int64_t token);
@@ -113,6 +116,7 @@ private:
pid_t mCallingPid;
uid_t mCallingUid;
int32_t mStrictModePolicy;
+ int32_t mLastTransactionBinderFlags;
};
}; // namespace android
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index f6582e6..a3e117f 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -377,6 +377,16 @@ int32_t IPCThreadState::getStrictModePolicy() const
return mStrictModePolicy;
}
+void IPCThreadState::setLastTransactionBinderFlags(int32_t flags)
+{
+ mLastTransactionBinderFlags = flags;
+}
+
+int32_t IPCThreadState::getLastTransactionBinderFlags() const
+{
+ return mLastTransactionBinderFlags;
+}
+
void IPCThreadState::restoreCallingIdentity(int64_t token)
{
mCallingUid = (int)(token>>32);
@@ -598,8 +608,10 @@ status_t IPCThreadState::clearDeathNotification(int32_t handle, BpBinder* proxy)
}
IPCThreadState::IPCThreadState()
- : mProcess(ProcessState::self()), mMyThreadId(androidGetTid()),
- mStrictModePolicy(0)
+ : mProcess(ProcessState::self()),
+ mMyThreadId(androidGetTid()),
+ mStrictModePolicy(0),
+ mLastTransactionBinderFlags(0)
{
pthread_setspecific(gTLS, this);
clearCaller();
@@ -983,11 +995,11 @@ status_t IPCThreadState::executeCommand(int32_t cmd)
}
if (tr.target.ptr) {
sp<BBinder> b((BBinder*)tr.cookie);
- const status_t error = b->transact(tr.code, buffer, &reply, 0);
+ const status_t error = b->transact(tr.code, buffer, &reply, tr.flags);
if (error < NO_ERROR) reply.setError(error);
-
+
} else {
- const status_t error = the_context_object->transact(tr.code, buffer, &reply, 0);
+ const status_t error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
if (error < NO_ERROR) reply.setError(error);
}
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 18f75df..f329ac4 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -464,7 +464,16 @@ bool Parcel::enforceInterface(const String16& interface,
if (threadState == NULL) {
threadState = IPCThreadState::self();
}
- threadState->setStrictModePolicy(strictPolicy);
+ if ((threadState->getLastTransactionBinderFlags() &
+ IBinder::FLAG_ONEWAY) != 0) {
+ // For one-way calls, the callee is running entirely
+ // disconnected from the caller, so disable StrictMode entirely.
+ // Not only does disk/network usage not impact the caller, but
+ // there's no way to commuicate back any violations anyway.
+ threadState->setStrictModePolicy(0);
+ } else {
+ threadState->setStrictModePolicy(strictPolicy);
+ }
const String16 str(readString16());
if (str == interface) {
return true;