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

Commit 89450a6c authored by Andrei Homescu's avatar Andrei Homescu Committed by Dmitriy Filchenko
Browse files

libbinder: Add getter for max supported FDs

Add a getRpcTransportModeMaxFds constant getter that
returns how many file descriptors are supported by
the current Rpc file descriptor transport mode.
This is in preparation for enabling file descriptor
support in the Trusty tests.

Bug: 242940548
Test: m binderRpcTest
Change-Id: Ia80fa0e992e2db6f29fef8f1361a208327a4ab37
parent 593a6ed1
Loading
Loading
Loading
Loading
+12 −30
Original line number Diff line number Diff line
@@ -1231,37 +1231,19 @@ status_t RpcState::validateParcel(const sp<RpcSession>& session, const Parcel& p
    }

    if (rpcFields->mFds && !rpcFields->mFds->empty()) {
        switch (session->getFileDescriptorTransportMode()) {
            case RpcSession::FileDescriptorTransportMode::NONE:
                *errorMsg =
                        "Parcel has file descriptors, but no file descriptor transport is enabled";
        auto fileDescriptorTransportMode = session->getFileDescriptorTransportMode();
        size_t maxFdsPerMsg = getRpcTransportModeMaxFds(fileDescriptorTransportMode);
        if (RpcSession::FileDescriptorTransportMode::NONE == fileDescriptorTransportMode) {
            *errorMsg = "Parcel has file descriptors, but no file descriptor transport is enabled";
            return FDS_NOT_ALLOWED;
            case RpcSession::FileDescriptorTransportMode::UNIX: {
                constexpr size_t kMaxFdsPerMsg = 253;
                if (rpcFields->mFds->size() > kMaxFdsPerMsg) {
                    std::stringstream ss;
                    ss << "Too many file descriptors in Parcel for unix domain socket: "
                       << rpcFields->mFds->size() << " (max is " << kMaxFdsPerMsg << ")";
                    *errorMsg = ss.str();
                    return BAD_VALUE;
        }
                break;
            }
            case RpcSession::FileDescriptorTransportMode::TRUSTY: {
                // Keep this in sync with trusty_ipc.h!!!
                // We could import that file here on Trusty, but it's not
                // available on Android
                constexpr size_t kMaxFdsPerMsg = 8;
                if (rpcFields->mFds->size() > kMaxFdsPerMsg) {
        if (rpcFields->mFds->size() > maxFdsPerMsg) {
            std::stringstream ss;
                    ss << "Too many file descriptors in Parcel for Trusty IPC connection: "
                       << rpcFields->mFds->size() << " (max is " << kMaxFdsPerMsg << ")";
            ss << "Too many file descriptors in Parcel: " << rpcFields->mFds->size() << " (max is "
               << maxFdsPerMsg << ")";
            *errorMsg = ss.str();
            return BAD_VALUE;
        }
                break;
            }
        }
    }

    return OK;
+16 −0
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
 */
#pragma once

#include <binder/RpcSession.h>

namespace android {

#pragma clang diagnostic push
@@ -167,4 +169,18 @@ static_assert(sizeof(RpcWireReply) == 20);

#pragma clang diagnostic pop

static inline size_t getRpcTransportModeMaxFds(RpcSession::FileDescriptorTransportMode mode) {
    switch (mode) {
        case RpcSession::FileDescriptorTransportMode::NONE:
            return 0;
        case RpcSession::FileDescriptorTransportMode::UNIX:
            return 253;
        case RpcSession::FileDescriptorTransportMode::TRUSTY:
            // Keep this in sync with trusty_ipc.h!!!
            // We could import that file here on Trusty, but it's not
            // available on Android
            return 8;
    }
}

} // namespace android
+12 −9
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@
#include <trusty/tipc.h>
#endif // BINDER_RPC_TO_TRUSTY_TEST

#include "../RpcWireFormat.h"
#include "../Utils.h"
#include "binderRpcTestCommon.h"
#include "binderRpcTestFixture.h"
@@ -1061,14 +1062,15 @@ TEST_P(BinderRpc, SendMaxFiles) {
        GTEST_SKIP() << "Would fail trivially (which is tested by BinderRpc::SendFiles)";
    }

    auto transportMode = RpcSession::FileDescriptorTransportMode::UNIX;
    auto proc = createRpcTestSocketServerProcess({
            .clientFileDescriptorTransportMode = RpcSession::FileDescriptorTransportMode::UNIX,
            .serverSupportedFileDescriptorTransportModes =
                    {RpcSession::FileDescriptorTransportMode::UNIX},
            .clientFileDescriptorTransportMode = transportMode,
            .serverSupportedFileDescriptorTransportModes = {transportMode},
    });

    size_t maxFds = getRpcTransportModeMaxFds(transportMode);
    std::vector<android::os::ParcelFileDescriptor> files;
    for (int i = 0; i < 253; i++) {
    for (size_t i = 0; i < maxFds; i++) {
        files.emplace_back(android::os::ParcelFileDescriptor(mockFileDescriptor("a")));
    }

@@ -1078,7 +1080,7 @@ TEST_P(BinderRpc, SendMaxFiles) {

    std::string result;
    EXPECT_TRUE(ReadFdToString(out.get(), &result));
    EXPECT_EQ(result, std::string(253, 'a'));
    EXPECT_EQ(result, std::string(maxFds, 'a'));
}

TEST_P(BinderRpc, SendTooManyFiles) {
@@ -1086,14 +1088,15 @@ TEST_P(BinderRpc, SendTooManyFiles) {
        GTEST_SKIP() << "Would fail trivially (which is tested by BinderRpc::SendFiles)";
    }

    auto transportMode = RpcSession::FileDescriptorTransportMode::UNIX;
    auto proc = createRpcTestSocketServerProcess({
            .clientFileDescriptorTransportMode = RpcSession::FileDescriptorTransportMode::UNIX,
            .serverSupportedFileDescriptorTransportModes =
                    {RpcSession::FileDescriptorTransportMode::UNIX},
            .clientFileDescriptorTransportMode = transportMode,
            .serverSupportedFileDescriptorTransportModes = {transportMode},
    });

    size_t maxFds = getRpcTransportModeMaxFds(transportMode);
    std::vector<android::os::ParcelFileDescriptor> files;
    for (int i = 0; i < 254; i++) {
    for (size_t i = 0; i < maxFds + 1; i++) {
        files.emplace_back(android::os::ParcelFileDescriptor(mockFileDescriptor("a")));
    }