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

Commit b465bea9 authored by Matt Gilbride's avatar Matt Gilbride Committed by Gerrit Code Review
Browse files

Merge "IPCThreadState::hasExplicitIdentity()"

parents 3cc0776c 85897678
Loading
Loading
Loading
Loading
+89 −6
Original line number Diff line number Diff line
@@ -394,14 +394,92 @@ void IPCThreadState::checkContextIsBinderForUse(const char* use) const {
    // context, so we don't abort
}

constexpr uint32_t encodeExplicitIdentity(bool hasExplicitIdentity, pid_t callingPid) {
    uint32_t as_unsigned = static_cast<uint32_t>(callingPid);
    if (hasExplicitIdentity) {
        return as_unsigned | (1 << 30);
    } else {
        return as_unsigned & ~(1 << 30);
    }
}

constexpr int64_t packCallingIdentity(bool hasExplicitIdentity, uid_t callingUid,
                                      pid_t callingPid) {
    // Calling PID is a 32-bit signed integer, but doesn't consume the entire 32 bit space.
    // To future-proof this and because we have extra capacity, we decided to also support -1,
    // since this constant is used to represent invalid UID in other places of the system.
    // Thus, we pack hasExplicitIdentity into the 2nd bit from the left.  This allows us to
    // preserve the (left-most) bit for the sign while also encoding the value of
    // hasExplicitIdentity.
    //               32b     |        1b         |         1b            |        30b
    // token = [ calling uid | calling pid(sign) | has explicit identity | calling pid(rest) ]
    uint64_t token = (static_cast<uint64_t>(callingUid) << 32) |
            encodeExplicitIdentity(hasExplicitIdentity, callingPid);
    return static_cast<int64_t>(token);
}

constexpr bool unpackHasExplicitIdentity(int64_t token) {
    return static_cast<int32_t>(token) & (1 << 30);
}

constexpr uid_t unpackCallingUid(int64_t token) {
    return static_cast<uid_t>(token >> 32);
}

constexpr pid_t unpackCallingPid(int64_t token) {
    int32_t encodedPid = static_cast<int32_t>(token);
    if (encodedPid & (1 << 31)) {
        return encodedPid | (1 << 30);
    } else {
        return encodedPid & ~(1 << 30);
    }
}

static_assert(unpackHasExplicitIdentity(packCallingIdentity(true, 1000, 9999)) == true,
              "pack true hasExplicit");

static_assert(unpackCallingUid(packCallingIdentity(true, 1000, 9999)) == 1000, "pack true uid");

static_assert(unpackCallingPid(packCallingIdentity(true, 1000, 9999)) == 9999, "pack true pid");

static_assert(unpackHasExplicitIdentity(packCallingIdentity(false, 1000, 9999)) == false,
              "pack false hasExplicit");

static_assert(unpackCallingUid(packCallingIdentity(false, 1000, 9999)) == 1000, "pack false uid");

static_assert(unpackCallingPid(packCallingIdentity(false, 1000, 9999)) == 9999, "pack false pid");

static_assert(unpackHasExplicitIdentity(packCallingIdentity(true, 1000, -1)) == true,
              "pack true (negative) hasExplicit");

static_assert(unpackCallingUid(packCallingIdentity(true, 1000, -1)) == 1000,
              "pack true (negative) uid");

static_assert(unpackCallingPid(packCallingIdentity(true, 1000, -1)) == -1,
              "pack true (negative) pid");

static_assert(unpackHasExplicitIdentity(packCallingIdentity(false, 1000, -1)) == false,
              "pack false (negative) hasExplicit");

static_assert(unpackCallingUid(packCallingIdentity(false, 1000, -1)) == 1000,
              "pack false (negative) uid");

static_assert(unpackCallingPid(packCallingIdentity(false, 1000, -1)) == -1,
              "pack false (negative) pid");

int64_t IPCThreadState::clearCallingIdentity()
{
    // ignore mCallingSid for legacy reasons
    int64_t token = ((int64_t)mCallingUid<<32) | mCallingPid;
    int64_t token = packCallingIdentity(mHasExplicitIdentity, mCallingUid, mCallingPid);
    clearCaller();
    mHasExplicitIdentity = true;
    return token;
}

bool IPCThreadState::hasExplicitIdentity() {
    return mHasExplicitIdentity;
}

void IPCThreadState::setStrictModePolicy(int32_t policy)
{
    mStrictModePolicy = policy;
@@ -474,9 +552,10 @@ ProcessState::CallRestriction IPCThreadState::getCallRestriction() const {

void IPCThreadState::restoreCallingIdentity(int64_t token)
{
    mCallingUid = (int)(token>>32);
    mCallingUid = unpackCallingUid(token);
    mCallingSid = nullptr;  // not enough data to restore
    mCallingPid = (int)token;
    mCallingPid = unpackCallingPid(token);
    mHasExplicitIdentity = unpackHasExplicitIdentity(token);
}

void IPCThreadState::clearCaller()
@@ -889,6 +968,7 @@ IPCThreadState::IPCThreadState()
        mCallRestriction(mProcess->mCallRestriction) {
    pthread_setspecific(gTLS, this);
    clearCaller();
    mHasExplicitIdentity = false;
    mIn.setDataCapacity(256);
    mOut.setDataCapacity(256);
}
@@ -1279,6 +1359,7 @@ status_t IPCThreadState::executeCommand(int32_t cmd)
            const pid_t origPid = mCallingPid;
            const char* origSid = mCallingSid;
            const uid_t origUid = mCallingUid;
            const bool origHasExplicitIdentity = mHasExplicitIdentity;
            const int32_t origStrictModePolicy = mStrictModePolicy;
            const int32_t origTransactionBinderFlags = mLastTransactionBinderFlags;
            const int32_t origWorkSource = mWorkSource;
@@ -1292,6 +1373,7 @@ status_t IPCThreadState::executeCommand(int32_t cmd)
            mCallingPid = tr.sender_pid;
            mCallingSid = reinterpret_cast<const char*>(tr_secctx.secctx);
            mCallingUid = tr.sender_euid;
            mHasExplicitIdentity = false;
            mLastTransactionBinderFlags = tr.flags;

            // ALOGI(">>>> TRANSACT from pid %d sid %s uid %d\n", mCallingPid,
@@ -1367,6 +1449,7 @@ status_t IPCThreadState::executeCommand(int32_t cmd)
            mCallingPid = origPid;
            mCallingSid = origSid;
            mCallingUid = origUid;
            mHasExplicitIdentity = origHasExplicitIdentity;
            mStrictModePolicy = origStrictModePolicy;
            mLastTransactionBinderFlags = origTransactionBinderFlags;
            mWorkSource = origWorkSource;
+2 −0
Original line number Diff line number Diff line
@@ -139,6 +139,7 @@ public:
            int64_t             clearCallingIdentity();
            // Restores PID/UID (not SID)
            void                restoreCallingIdentity(int64_t token);
            bool hasExplicitIdentity();

            status_t            setupPolling(int* fd);
            status_t            handlePolledCommands();
@@ -241,6 +242,7 @@ private:
            bool                mPropagateWorkSource;
            bool                mIsLooper;
            bool mIsFlushing;
            bool mHasExplicitIdentity;
            int32_t             mStrictModePolicy;
            int32_t             mLastTransactionBinderFlags;
            CallRestriction     mCallRestriction;