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

Commit 86124ca8 authored by Andrei Homescu's avatar Andrei Homescu
Browse files

libbinder: switch sockaddr to byte array in RpcServer

A few methods in RpcServer.cpp take a sockaddr or
sockaddr_storage parameter. To support operating systems
without sockets, e.g. Trusty, this switches those
types to void* and std::array<uint8_t, 128>, respectively.

Test: atest binderRpcTest
Bug: 224644083
Change-Id: I9773a4cf0aedd5ebec22a10cea5b1593067632c5
parent c56d0ecb
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -135,7 +135,7 @@ void RpcServer::setRootObjectWeak(const wp<IBinder>& binder) {
    mRootObjectWeak = binder;
}
void RpcServer::setPerSessionRootObject(
        std::function<sp<IBinder>(const sockaddr*, socklen_t)>&& makeObject) {
        std::function<sp<IBinder>(const void*, size_t)>&& makeObject) {
    std::lock_guard<std::mutex> _l(mLock);
    mRootObject.clear();
    mRootObjectWeak.clear();
@@ -178,14 +178,16 @@ void RpcServer::join() {

    status_t status;
    while ((status = mShutdownTrigger->triggerablePoll(mServer, POLLIN)) == OK) {
        sockaddr_storage addr;
        socklen_t addrLen = sizeof(addr);
        std::array<uint8_t, kRpcAddressSize> addr;
        static_assert(addr.size() >= sizeof(sockaddr_storage), "kRpcAddressSize is too small");

        socklen_t addrLen = addr.size();
        unique_fd clientFd(
                TEMP_FAILURE_RETRY(accept4(mServer.get(), reinterpret_cast<sockaddr*>(&addr),
                TEMP_FAILURE_RETRY(accept4(mServer.get(), reinterpret_cast<sockaddr*>(addr.data()),
                                           &addrLen, SOCK_CLOEXEC | SOCK_NONBLOCK)));

        LOG_ALWAYS_FATAL_IF(addrLen > static_cast<socklen_t>(sizeof(addr)), "Truncated address");
        LOG_ALWAYS_FATAL_IF(addrLen > static_cast<socklen_t>(sizeof(sockaddr_storage)),
                            "Truncated address");

        if (clientFd < 0) {
            ALOGE("Could not accept4 socket: %s", strerror(errno));
@@ -268,7 +270,7 @@ size_t RpcServer::numUninitializedSessions() {
}

void RpcServer::establishConnection(sp<RpcServer>&& server, base::unique_fd clientFd,
                                    const sockaddr_storage addr, socklen_t addrLen) {
                                    std::array<uint8_t, kRpcAddressSize> addr, size_t addrLen) {
    // mShutdownTrigger can only be cleared once connection threads have joined.
    // It must be set before this thread is started
    LOG_ALWAYS_FATAL_IF(server->mShutdownTrigger == nullptr);
@@ -397,9 +399,7 @@ void RpcServer::establishConnection(sp<RpcServer>&& server, base::unique_fd clie
            // if null, falls back to server root
            sp<IBinder> sessionSpecificRoot;
            if (server->mRootObjectFactory != nullptr) {
                sessionSpecificRoot =
                        server->mRootObjectFactory(reinterpret_cast<const sockaddr*>(&addr),
                                                   addrLen);
                sessionSpecificRoot = server->mRootObjectFactory(addr.data(), addrLen);
                if (sessionSpecificRoot == nullptr) {
                    ALOGE("Warning: server returned null from root object factory");
                }
+14 −5
Original line number Diff line number Diff line
@@ -125,9 +125,17 @@ public:
     */
    void setRootObjectWeak(const wp<IBinder>& binder);
    /**
     * Allows a root object to be created for each session
     */
    void setPerSessionRootObject(std::function<sp<IBinder>(const sockaddr*, socklen_t)>&& object);
     * Allows a root object to be created for each session.
     *
     * Takes one argument: a callable that is invoked once per new session.
     * The callable takes two arguments: a type-erased pointer to an OS- and
     * transport-specific address structure, e.g., sockaddr_vm for vsock, and
     * an integer representing the size in bytes of that structure. The
     * callable should validate the size, then cast the type-erased pointer
     * to a pointer to the actual type of the address, e.g., const void* to
     * const sockaddr_vm*.
     */
    void setPerSessionRootObject(std::function<sp<IBinder>(const void*, size_t)>&& object);
    sp<IBinder> getRootObject();

    /**
@@ -177,8 +185,9 @@ private:
    void onSessionAllIncomingThreadsEnded(const sp<RpcSession>& session) override;
    void onSessionIncomingThreadEnded() override;

    static constexpr size_t kRpcAddressSize = 128;
    static void establishConnection(sp<RpcServer>&& server, base::unique_fd clientFd,
                                    const sockaddr_storage addr, socklen_t addrLen);
                                    std::array<uint8_t, kRpcAddressSize> addr, size_t addrLen);
    [[nodiscard]] status_t setupSocketServer(const RpcSocketAddress& address);

    const std::unique_ptr<RpcTransportCtx> mCtx;
@@ -192,7 +201,7 @@ private:
    std::map<std::thread::id, std::thread> mConnectingThreads;
    sp<IBinder> mRootObject;
    wp<IBinder> mRootObjectWeak;
    std::function<sp<IBinder>(const sockaddr*, socklen_t)> mRootObjectFactory;
    std::function<sp<IBinder>(const void*, size_t)> mRootObjectFactory;
    std::map<std::vector<uint8_t>, sp<RpcSession>> mSessions;
    std::unique_ptr<FdTrigger> mShutdownTrigger;
    std::condition_variable mShutdownCv;
+2 −2
Original line number Diff line number Diff line
@@ -38,10 +38,10 @@ bool RunRpcServerWithFactory(AIBinder* (*factory)(unsigned int cid, void* contex
                   << " error: " << statusToString(status).c_str();
        return false;
    }
    server->setPerSessionRootObject([=](const sockaddr* addr, socklen_t addrlen) {
        LOG_ALWAYS_FATAL_IF(addr->sa_family != AF_VSOCK, "address is not a vsock");
    server->setPerSessionRootObject([=](const void* addr, size_t addrlen) {
        LOG_ALWAYS_FATAL_IF(addrlen < sizeof(sockaddr_vm), "sockaddr is truncated");
        const sockaddr_vm* vaddr = reinterpret_cast<const sockaddr_vm*>(addr);
        LOG_ALWAYS_FATAL_IF(vaddr->svm_family != AF_VSOCK, "address is not a vsock");
        return AIBinder_toPlatformBinder(factory(vaddr->svm_cid, factoryContext));
    });

+5 −2
Original line number Diff line number Diff line
@@ -650,8 +650,11 @@ public:
                .proc = createRpcTestSocketServerProcess(
                        options,
                        [&](const sp<RpcServer>& server) {
                            server->setPerSessionRootObject([&](const sockaddr* addr,
                                                                socklen_t len) {
                            server->setPerSessionRootObject([&](const void* addrPtr, size_t len) {
                                // UNIX sockets with abstract addresses return
                                // sizeof(sa_family_t)==2 in addrlen
                                CHECK_GE(len, sizeof(sa_family_t));
                                const sockaddr* addr = reinterpret_cast<const sockaddr*>(addrPtr);
                                sp<MyBinderRpcTest> service = sp<MyBinderRpcTest>::make();
                                switch (addr->sa_family) {
                                    case AF_UNIX: