Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5273603e authored by Brad Fitzpatrick's avatar Brad Fitzpatrick
Browse files

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
parent 00807f5a
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -44,6 +44,9 @@ 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
+17 −5
Original line number Diff line number Diff line
@@ -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);
            }
            
+10 −1
Original line number Diff line number Diff line
@@ -464,7 +464,16 @@ bool Parcel::enforceInterface(const String16& interface,
    if (threadState == NULL) {
        threadState = IPCThreadState::self();
    }
    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;