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

Commit ef9f0459 authored by Dmitriy Filchenko (xWF)'s avatar Dmitriy Filchenko (xWF) Committed by Android (Google) Code Review
Browse files

Merge "libbinder: Add getter for max supported FDs" into main

parents 22555c5c 89450a6c
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")));
    }