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

Commit 758f0040 authored by Steven Moreland's avatar Steven Moreland Committed by Automerger Merge Worker
Browse files

Merge changes Id8fc889f,I2145ad0e am: 5426122b am: 08cb54f4 am: da55afdb

Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/1707789

Change-Id: I22ca3bb1e715017eb3378f2e4a0f3a09b2331de5
parents 9e32ff84 da55afdb
Loading
Loading
Loading
Loading
+35 −9
Original line number Original line Diff line number Diff line
@@ -366,19 +366,45 @@ status_t IPCThreadState::clearLastError()


pid_t IPCThreadState::getCallingPid() const
pid_t IPCThreadState::getCallingPid() const
{
{
    checkContextIsBinderForUse(__func__);
    return mCallingPid;
    return mCallingPid;
}
}


const char* IPCThreadState::getCallingSid() const
const char* IPCThreadState::getCallingSid() const
{
{
    checkContextIsBinderForUse(__func__);
    return mCallingSid;
    return mCallingSid;
}
}


uid_t IPCThreadState::getCallingUid() const
uid_t IPCThreadState::getCallingUid() const
{
{
    checkContextIsBinderForUse(__func__);
    return mCallingUid;
    return mCallingUid;
}
}


IPCThreadState::SpGuard* IPCThreadState::pushGetCallingSpGuard(SpGuard* guard) {
    SpGuard* orig = mServingStackPointerGuard;
    mServingStackPointerGuard = guard;
    return orig;
}

void IPCThreadState::restoreGetCallingSpGuard(SpGuard* guard) {
    mServingStackPointerGuard = guard;
}

void IPCThreadState::checkContextIsBinderForUse(const char* use) const {
    if (mServingStackPointerGuard == nullptr) return;

    if (!mServingStackPointer || mServingStackPointerGuard < mServingStackPointer) {
        LOG_ALWAYS_FATAL("In context %s, %s does not make sense.",
                         mServingStackPointerGuard->context, use);
    }

    // in the case mServingStackPointer is deeper in the stack than the guard,
    // we must be serving a binder transaction (maybe nested). This is a binder
    // context, so we don't abort
}

int64_t IPCThreadState::clearCallingIdentity()
int64_t IPCThreadState::clearCallingIdentity()
{
{
    // ignore mCallingSid for legacy reasons
    // ignore mCallingSid for legacy reasons
@@ -849,13 +875,13 @@ status_t IPCThreadState::clearDeathNotification(int32_t handle, BpBinder* proxy)
IPCThreadState::IPCThreadState()
IPCThreadState::IPCThreadState()
      : mProcess(ProcessState::self()),
      : mProcess(ProcessState::self()),
        mServingStackPointer(nullptr),
        mServingStackPointer(nullptr),
        mServingStackPointerGuard(nullptr),
        mWorkSource(kUnsetWorkSource),
        mWorkSource(kUnsetWorkSource),
        mPropagateWorkSource(false),
        mPropagateWorkSource(false),
        mIsLooper(false),
        mIsLooper(false),
        mStrictModePolicy(0),
        mStrictModePolicy(0),
        mLastTransactionBinderFlags(0),
        mLastTransactionBinderFlags(0),
      mCallRestriction(mProcess->mCallRestriction)
        mCallRestriction(mProcess->mCallRestriction) {
{
    pthread_setspecific(gTLS, this);
    pthread_setspecific(gTLS, this);
    clearCaller();
    clearCaller();
    mIn.setDataCapacity(256);
    mIn.setDataCapacity(256);
+16 −0
Original line number Original line Diff line number Diff line
@@ -18,7 +18,9 @@


#include "RpcState.h"
#include "RpcState.h"


#include <android-base/scopeguard.h>
#include <binder/BpBinder.h>
#include <binder/BpBinder.h>
#include <binder/IPCThreadState.h>
#include <binder/RpcServer.h>
#include <binder/RpcServer.h>


#include "Debug.h"
#include "Debug.h"
@@ -28,6 +30,8 @@


namespace android {
namespace android {


using base::ScopeGuard;

RpcState::RpcState() {}
RpcState::RpcState() {}
RpcState::~RpcState() {}
RpcState::~RpcState() {}


@@ -470,6 +474,18 @@ status_t RpcState::getAndExecuteCommand(const base::unique_fd& fd, const sp<RpcS


status_t RpcState::processServerCommand(const base::unique_fd& fd, const sp<RpcSession>& session,
status_t RpcState::processServerCommand(const base::unique_fd& fd, const sp<RpcSession>& session,
                                        const RpcWireHeader& command) {
                                        const RpcWireHeader& command) {
    IPCThreadState* kernelBinderState = IPCThreadState::selfOrNull();
    IPCThreadState::SpGuard spGuard{"processing binder RPC command"};
    IPCThreadState::SpGuard* origGuard;
    if (kernelBinderState != nullptr) {
        origGuard = kernelBinderState->pushGetCallingSpGuard(&spGuard);
    }
    ScopeGuard guardUnguard = [&]() {
        if (kernelBinderState != nullptr) {
            kernelBinderState->restoreGetCallingSpGuard(origGuard);
        }
    };

    switch (command.command) {
    switch (command.command) {
        case RPC_COMMAND_TRANSACT:
        case RPC_COMMAND_TRANSACT:
            return processTransact(fd, session, command);
            return processTransact(fd, session, command);
+27 −0
Original line number Original line Diff line number Diff line
@@ -81,6 +81,32 @@ public:
             */
             */
            uid_t               getCallingUid() const;
            uid_t               getCallingUid() const;


            /**
             * Make it an abort to rely on getCalling* for a section of
             * execution.
             *
             * Usage:
             *     IPCThreadState::SpGuard guard { "..." };
             *     auto* orig = pushGetCallingSpGuard(&guard);
             *     {
             *         // will abort if you call getCalling*, unless you are
             *         // serving a nested binder transaction
             *     }
             *     restoreCallingSpGuard(orig);
             */
            struct SpGuard {
                const char* context;
            };
            SpGuard* pushGetCallingSpGuard(SpGuard* guard);
            void restoreGetCallingSpGuard(SpGuard* guard);
            /**
             * Used internally by getCalling*. Can also be used to assert that
             * you are in a binder context (getCalling* is valid). This is
             * intentionally not exposed as a boolean API since code should be
             * written to know its environment.
             */
            void checkContextIsBinderForUse(const char* use) const;

            void                setStrictModePolicy(int32_t policy);
            void                setStrictModePolicy(int32_t policy);
            int32_t             getStrictModePolicy() const;
            int32_t             getStrictModePolicy() const;


@@ -203,6 +229,7 @@ private:
            Parcel              mOut;
            Parcel              mOut;
            status_t            mLastError;
            status_t            mLastError;
            const void*         mServingStackPointer;
            const void*         mServingStackPointer;
            SpGuard* mServingStackPointerGuard;
            pid_t               mCallingPid;
            pid_t               mCallingPid;
            const char*         mCallingSid;
            const char*         mCallingSid;
            uid_t               mCallingUid;
            uid_t               mCallingUid;
+2 −0
Original line number Original line Diff line number Diff line
@@ -55,4 +55,6 @@ interface IBinderRpcTest {
    oneway void sleepMsAsync(int ms);
    oneway void sleepMsAsync(int ms);


    void die(boolean cleanup);
    void die(boolean cleanup);

    void useKernelBinderCallingId();
}
}
+36 −0
Original line number Original line Diff line number Diff line
@@ -73,6 +73,7 @@ enum BinderLibTestTranscationCode {
    BINDER_LIB_TEST_REGISTER_SERVER,
    BINDER_LIB_TEST_REGISTER_SERVER,
    BINDER_LIB_TEST_ADD_SERVER,
    BINDER_LIB_TEST_ADD_SERVER,
    BINDER_LIB_TEST_ADD_POLL_SERVER,
    BINDER_LIB_TEST_ADD_POLL_SERVER,
    BINDER_LIB_TEST_USE_CALLING_GUARD_TRANSACTION,
    BINDER_LIB_TEST_CALL_BACK,
    BINDER_LIB_TEST_CALL_BACK,
    BINDER_LIB_TEST_CALL_BACK_VERIFY_BUF,
    BINDER_LIB_TEST_CALL_BACK_VERIFY_BUF,
    BINDER_LIB_TEST_DELAYED_CALL_BACK,
    BINDER_LIB_TEST_DELAYED_CALL_BACK,
@@ -604,6 +605,24 @@ TEST_F(BinderLibTest, CallBack)
    EXPECT_THAT(callBack->getResult(), StatusEq(NO_ERROR));
    EXPECT_THAT(callBack->getResult(), StatusEq(NO_ERROR));
}
}


TEST_F(BinderLibTest, NoBinderCallContextGuard) {
    IPCThreadState::SpGuard spGuard{"NoBinderCallContext"};
    IPCThreadState::SpGuard *origGuard = IPCThreadState::self()->pushGetCallingSpGuard(&spGuard);

    // yes, this test uses threads, but it's careful and uses fork in addServer
    EXPECT_DEATH({ IPCThreadState::self()->getCallingPid(); },
                 "In context NoBinderCallContext, getCallingPid does not make sense.");

    IPCThreadState::self()->restoreGetCallingSpGuard(origGuard);
}

TEST_F(BinderLibTest, BinderCallContextGuard) {
    sp<IBinder> binder = addServer();
    Parcel data, reply;
    EXPECT_THAT(binder->transact(BINDER_LIB_TEST_USE_CALLING_GUARD_TRANSACTION, data, &reply),
                StatusEq(DEAD_OBJECT));
}

TEST_F(BinderLibTest, AddServer)
TEST_F(BinderLibTest, AddServer)
{
{
    sp<IBinder> server = addServer();
    sp<IBinder> server = addServer();
@@ -1262,6 +1281,18 @@ class BinderLibTestService : public BBinder
                pthread_mutex_unlock(&m_serverWaitMutex);
                pthread_mutex_unlock(&m_serverWaitMutex);
                return ret;
                return ret;
            }
            }
            case BINDER_LIB_TEST_USE_CALLING_GUARD_TRANSACTION: {
                IPCThreadState::SpGuard spGuard{"GuardInBinderTransaction"};
                IPCThreadState::SpGuard *origGuard =
                        IPCThreadState::self()->pushGetCallingSpGuard(&spGuard);

                // if the guard works, this should abort
                (void)IPCThreadState::self()->getCallingPid();

                IPCThreadState::self()->restoreGetCallingSpGuard(origGuard);
                return NO_ERROR;
            }

            case BINDER_LIB_TEST_GETPID:
            case BINDER_LIB_TEST_GETPID:
                reply->writeInt32(getpid());
                reply->writeInt32(getpid());
                return NO_ERROR;
                return NO_ERROR;
@@ -1489,6 +1520,11 @@ int run_server(int index, int readypipefd, bool usePoll)
{
{
    binderLibTestServiceName += String16(binderserversuffix);
    binderLibTestServiceName += String16(binderserversuffix);


    // Testing to make sure that calls that we are serving can use getCallin*
    // even though we don't here.
    IPCThreadState::SpGuard spGuard{"main server thread"};
    (void)IPCThreadState::self()->pushGetCallingSpGuard(&spGuard);

    status_t ret;
    status_t ret;
    sp<IServiceManager> sm = defaultServiceManager();
    sp<IServiceManager> sm = defaultServiceManager();
    BinderLibTestService* testServicePtr;
    BinderLibTestService* testServicePtr;
Loading