diff --git a/include/binder/IPCThreadState.h b/include/binder/IPCThreadState.h index 04e24d29a..b54718f1a 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 f6582e6aa..a3e117f45 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 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 18f75df2e..f329ac464 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;