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

Commit eb258ff0 authored by Steven Moreland's avatar Steven Moreland
Browse files

libbinder: binder RPC - using getCalling* aborts

Broken code? Now you know!

Fixes: 186647790
Test: binderRpcTest (on host and device)
Change-Id: Id8fc889f4998b98f8c3a5ae0e054741e0e83c785
parent 8e5f3b45
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -18,7 +18,9 @@

#include "RpcState.h"

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

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

namespace android {

using base::ScopeGuard;

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,
                                        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) {
        case RPC_COMMAND_TRANSACT:
            return processTransact(fd, session, command);
+2 −0
Original line number Diff line number Diff line
@@ -55,4 +55,6 @@ interface IBinderRpcTest {
    oneway void sleepMsAsync(int ms);

    void die(boolean cleanup);

    void useKernelBinderCallingId();
}
+21 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <android/binder_libbinder.h>
#include <binder/Binder.h>
#include <binder/BpBinder.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <binder/RpcServer.h>
@@ -178,6 +179,13 @@ public:
            _exit(1);
        }
    }
    Status useKernelBinderCallingId() override {
        // this is WRONG! It does not make sense when using RPC binder, and
        // because it is SO wrong, and so much code calls this, it should abort!

        (void)IPCThreadState::self()->getCallingPid();
        return Status::ok();
    }
};
sp<IBinder> MyBinderRpcTest::mHeldBinder;

@@ -874,6 +882,19 @@ TEST_P(BinderRpc, Die) {
    }
}

TEST_P(BinderRpc, UseKernelBinderCallingId) {
    auto proc = createRpcTestSocketServerProcess(1);

    // we can't allocate IPCThreadState so actually the first time should
    // succeed :(
    EXPECT_OK(proc.rootIface->useKernelBinderCallingId());

    // second time! we catch the error :)
    EXPECT_EQ(DEAD_OBJECT, proc.rootIface->useKernelBinderCallingId().transactionError());

    proc.expectInvalid = true;
}

TEST_P(BinderRpc, WorksWithLibbinderNdkPing) {
    auto proc = createRpcTestSocketServerProcess(1);