Loading libs/binder/RpcState.cpp +12 −30 Original line number Diff line number Diff line Loading @@ -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; Loading libs/binder/RpcWireFormat.h +16 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ */ #pragma once #include <binder/RpcSession.h> namespace android { #pragma clang diagnostic push Loading Loading @@ -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 libs/binder/tests/binderRpcTest.cpp +12 −9 Original line number Diff line number Diff line Loading @@ -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" Loading Loading @@ -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"))); } Loading @@ -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) { Loading @@ -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"))); } Loading Loading
libs/binder/RpcState.cpp +12 −30 Original line number Diff line number Diff line Loading @@ -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; Loading
libs/binder/RpcWireFormat.h +16 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ */ #pragma once #include <binder/RpcSession.h> namespace android { #pragma clang diagnostic push Loading Loading @@ -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
libs/binder/tests/binderRpcTest.cpp +12 −9 Original line number Diff line number Diff line Loading @@ -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" Loading Loading @@ -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"))); } Loading @@ -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) { Loading @@ -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"))); } Loading