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

Commit 7bdc94ac authored by Olivier Gaillard's avatar Olivier Gaillard Committed by Android (Google) Code Review
Browse files

Merge "Add worksource support to binder calls."

parents 49fcae32 0e0f1de5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -274,6 +274,7 @@ int svcmgr_handler(struct binder_state *bs,
    // Note that we ignore the strict_policy and don't propagate it
    // further (since we do no outbound RPCs anyway).
    strict_policy = bio_get_uint32(msg);
    bio_get_uint32(msg);  // Ignore worksource header.
    s = bio_get_string16(msg, &len);
    if (s == NULL) {
        return -1;
+24 −0
Original line number Diff line number Diff line
@@ -109,6 +109,10 @@ static const char *kCommandStrings[] = {
    "BC_DEAD_BINDER_DONE"
};

// The work source represents the UID of the process we should attribute the transaction to.
// We use -1 to specify that the work source was not set using #setWorkSource.
static const int kUnsetWorkSource = -1;

static const char* getReturnString(uint32_t cmd)
{
    size_t idx = cmd & 0xff;
@@ -383,6 +387,25 @@ int32_t IPCThreadState::getStrictModePolicy() const
    return mStrictModePolicy;
}

uid_t IPCThreadState::setWorkSource(uid_t uid)
{
    uid_t returnValue = mWorkSource;
    mWorkSource = uid;
    return returnValue;
}

uid_t IPCThreadState::getWorkSource() const
{
    return mWorkSource;
}

uid_t IPCThreadState::clearWorkSource()
{
    uid_t returnValue = mWorkSource;
    mWorkSource = kUnsetWorkSource;
    return returnValue;
}

void IPCThreadState::setLastTransactionBinderFlags(int32_t flags)
{
    mLastTransactionBinderFlags = flags;
@@ -736,6 +759,7 @@ status_t IPCThreadState::clearDeathNotification(int32_t handle, BpBinder* proxy)

IPCThreadState::IPCThreadState()
    : mProcess(ProcessState::self()),
      mWorkSource(kUnsetWorkSource),
      mStrictModePolicy(0),
      mLastTransactionBinderFlags(0)
{
+6 −0
Original line number Diff line number Diff line
@@ -601,6 +601,7 @@ status_t Parcel::writeInterfaceToken(const String16& interface)
{
    writeInt32(IPCThreadState::self()->getStrictModePolicy() |
               STRICT_MODE_PENALTY_GATHER);
    writeInt32(IPCThreadState::self()->getWorkSource());
    // currently the interface identification token is just its name as a string
    return writeString16(interface);
}
@@ -613,6 +614,7 @@ bool Parcel::checkInterface(IBinder* binder) const
bool Parcel::enforceInterface(const String16& interface,
                              IPCThreadState* threadState) const
{
    // StrictModePolicy.
    int32_t strictPolicy = readInt32();
    if (threadState == nullptr) {
        threadState = IPCThreadState::self();
@@ -627,6 +629,10 @@ bool Parcel::enforceInterface(const String16& interface,
    } else {
      threadState->setStrictModePolicy(strictPolicy);
    }
    // WorkSource.
    int32_t workSource = readInt32();
    threadState->setWorkSource(workSource);
    // Interface descriptor.
    const String16 str(readString16());
    if (str == interface) {
        return true;
+10 −0
Original line number Diff line number Diff line
@@ -47,6 +47,13 @@ public:
            void                setStrictModePolicy(int32_t policy);
            int32_t             getStrictModePolicy() const;

            // See Binder#setThreadWorkSource in Binder.java.
            uid_t               setWorkSource(uid_t uid);
            // See Binder#getThreadWorkSource in Binder.java.
            uid_t               getWorkSource() const;
            // See Binder#clearThreadWorkSource in Binder.java.
            uid_t               clearWorkSource();

            void                setLastTransactionBinderFlags(int32_t flags);
            int32_t             getLastTransactionBinderFlags() const;

@@ -155,6 +162,9 @@ private:
            status_t            mLastError;
            pid_t               mCallingPid;
            uid_t               mCallingUid;
            // The UID of the process who is responsible for this transaction.
            // This is used for resource attribution.
            int32_t             mWorkSource;
            int32_t             mStrictModePolicy;
            int32_t             mLastTransactionBinderFlags;
            IPCThreadStateBase  *mIPCThreadStateBase;
+43 −0
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ enum BinderLibTestTranscationCode {
    BINDER_LIB_TEST_DELAYED_EXIT_TRANSACTION,
    BINDER_LIB_TEST_GET_PTR_SIZE_TRANSACTION,
    BINDER_LIB_TEST_CREATE_BINDER_TRANSACTION,
    BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION,
};

pid_t start_server_process(int arg2, bool usePoll = false)
@@ -938,6 +939,43 @@ TEST_F(BinderLibTest, OnewayQueueing)
    EXPECT_EQ(NO_ERROR, ret);
}

TEST_F(BinderLibTest, WorkSourceUnsetByDefault)
{
    status_t ret;
    Parcel data, reply;
    data.writeInterfaceToken(binderLibTestServiceName);
    ret = m_server->transact(BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION, data, &reply);
    EXPECT_EQ(-1, reply.readInt32());
    EXPECT_EQ(NO_ERROR, ret);
}

TEST_F(BinderLibTest, WorkSourceSet)
{
    status_t ret;
    Parcel data, reply;
    uid_t previousWorkSource = IPCThreadState::self()->setWorkSource(100);
    data.writeInterfaceToken(binderLibTestServiceName);
    ret = m_server->transact(BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION, data, &reply);
    EXPECT_EQ(100, reply.readInt32());
    EXPECT_EQ(-1, previousWorkSource);
    EXPECT_EQ(NO_ERROR, ret);
}

TEST_F(BinderLibTest, WorkSourceCleared)
{
    status_t ret;
    Parcel data, reply;

    IPCThreadState::self()->setWorkSource(100);
    uid_t previousWorkSource = IPCThreadState::self()->clearWorkSource();
    data.writeInterfaceToken(binderLibTestServiceName);
    ret = m_server->transact(BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION, data, &reply);

    EXPECT_EQ(-1, reply.readInt32());
    EXPECT_EQ(100, previousWorkSource);
    EXPECT_EQ(NO_ERROR, ret);
}

class BinderLibTestService : public BBinder
{
    public:
@@ -1236,6 +1274,11 @@ class BinderLibTestService : public BBinder
                }
                return NO_ERROR;
            }
            case BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION: {
                data.enforceInterface(binderLibTestServiceName);
                reply->writeInt32(IPCThreadState::self()->getWorkSource());
                return NO_ERROR;
            }
            default:
                return UNKNOWN_TRANSACTION;
            };