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

Commit 364b3fe3 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "libbinder: add ancillaryFd support in RpcTransportTipcTrusty" am:...

Merge "libbinder: add ancillaryFd support in RpcTransportTipcTrusty" am: 8eb983ce am: 67296dd1 am: e0358af0

Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/2189664



Change-Id: I4accc787dee4125c06e551f1203c4ab8d994ca2b
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents b8dda5c2 e0358af0
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -1439,7 +1439,8 @@ status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership) {
            case RpcSession::FileDescriptorTransportMode::NONE: {
                return FDS_NOT_ALLOWED;
            }
            case RpcSession::FileDescriptorTransportMode::UNIX: {
            case RpcSession::FileDescriptorTransportMode::UNIX:
            case RpcSession::FileDescriptorTransportMode::TRUSTY: {
                if (rpcFields->mFds == nullptr) {
                    rpcFields->mFds = std::make_unique<decltype(rpcFields->mFds)::element_type>();
                }
+15 −0
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ static bool enableAncillaryFds(RpcSession::FileDescriptorTransportMode mode) {
        case RpcSession::FileDescriptorTransportMode::NONE:
            return false;
        case RpcSession::FileDescriptorTransportMode::UNIX:
        case RpcSession::FileDescriptorTransportMode::TRUSTY:
            return true;
    }
}
@@ -1207,6 +1208,20 @@ status_t RpcState::validateParcel(const sp<RpcSession>& session, const Parcel& p
                                             rpcFields->mFds->size(), kMaxFdsPerMsg);
                    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) {
                    *errorMsg = StringPrintf("Too many file descriptors in Parcel for Trusty "
                                             "IPC connection: %zu (max is %zu)",
                                             rpcFields->mFds->size(), kMaxFdsPerMsg);
                    return BAD_VALUE;
                }
                break;
            }
        }
    }
+2 −0
Original line number Diff line number Diff line
@@ -100,6 +100,8 @@ public:
        NONE = 0,
        // Send file descriptors via unix domain socket ancillary data.
        UNIX = 1,
        // Send file descriptors as Trusty IPC handles.
        TRUSTY = 2,
    };

    /**
+10 −3
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

#if defined(TRUSTY_USERSPACE)
#include <openssl/rand.h>
#include <trusty_ipc.h>
#else
#include <lib/rand/rand.h>
#endif
@@ -23,6 +24,7 @@
#include <binder/RpcTransportTipcTrusty.h>

#include "../OS.h"
#include "TrustyStatus.h"

using android::base::Result;

@@ -43,9 +45,14 @@ status_t getRandomBytes(uint8_t* data, size_t size) {
#endif // TRUSTY_USERSPACE
}

status_t dupFileDescriptor(int /*oldFd*/, int* /*newFd*/) {
    // TODO: implement separately
    return INVALID_OPERATION;
status_t dupFileDescriptor(int oldFd, int* newFd) {
    int res = dup(oldFd);
    if (res < 0) {
        return statusFromTrusty(res);
    }

    *newFd = res;
    return OK;
}

std::unique_ptr<RpcTransportCtxFactory> makeDefaultRpcTransportCtxFactory() {
+53 −6
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

#define LOG_TAG "RpcTransportTipcTrusty"

#include <inttypes.h>
#include <trusty_ipc.h>

#include <binder/RpcSession.h>
@@ -47,7 +48,7 @@ public:
    status_t interruptableWriteFully(
            FdTrigger* /*fdTrigger*/, iovec* iovs, int niovs,
            const std::optional<android::base::function_ref<status_t()>>& /*altPoll*/,
            const std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* /*ancillaryFds*/)
            const std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds)
            override {
        if (niovs < 0) {
            return BAD_VALUE;
@@ -58,12 +59,32 @@ public:
            size += iovs[i].iov_len;
        }

        handle_t msgHandles[IPC_MAX_MSG_HANDLES];
        ipc_msg_t msg{
                .num_iov = static_cast<uint32_t>(niovs),
                .iov = iovs,
                .num_handles = 0, // TODO: add ancillaryFds
                .num_handles = 0,
                .handles = nullptr,
        };

        if (ancillaryFds != nullptr && !ancillaryFds->empty()) {
            if (ancillaryFds->size() > IPC_MAX_MSG_HANDLES) {
                // This shouldn't happen because we check the FD count in RpcState.
                ALOGE("Saw too many file descriptors in RpcTransportCtxTipcTrusty: "
                      "%zu (max is %u). Aborting session.",
                      ancillaryFds->size(), IPC_MAX_MSG_HANDLES);
                return BAD_VALUE;
            }

            for (size_t i = 0; i < ancillaryFds->size(); i++) {
                msgHandles[i] =
                        std::visit([](const auto& fd) { return fd.get(); }, ancillaryFds->at(i));
            }

            msg.num_handles = ancillaryFds->size();
            msg.handles = msgHandles;
        }

        ssize_t rc = send_msg(mSocket.fd.get(), &msg);
        if (rc == ERR_NOT_ENOUGH_BUFFER) {
            // Peer is blocked, wait until it unblocks.
@@ -97,8 +118,7 @@ public:
    status_t interruptableReadFully(
            FdTrigger* /*fdTrigger*/, iovec* iovs, int niovs,
            const std::optional<android::base::function_ref<status_t()>>& /*altPoll*/,
            std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* /*ancillaryFds*/)
            override {
            std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds) override {
        if (niovs < 0) {
            return BAD_VALUE;
        }
@@ -124,11 +144,16 @@ public:
                return status;
            }

            LOG_ALWAYS_FATAL_IF(mMessageInfo.num_handles > IPC_MAX_MSG_HANDLES,
                                "Received too many handles %" PRIu32, mMessageInfo.num_handles);
            bool haveHandles = mMessageInfo.num_handles != 0;
            handle_t msgHandles[IPC_MAX_MSG_HANDLES];

            ipc_msg_t msg{
                    .num_iov = static_cast<uint32_t>(niovs),
                    .iov = iovs,
                    .num_handles = 0, // TODO: support ancillaryFds
                    .handles = nullptr,
                    .num_handles = mMessageInfo.num_handles,
                    .handles = haveHandles ? msgHandles : 0,
            };
            ssize_t rc = read_msg(mSocket.fd.get(), mMessageInfo.id, mMessageOffset, &msg);
            if (rc < 0) {
@@ -141,6 +166,28 @@ public:
                                "Message offset exceeds length %zu/%zu", mMessageOffset,
                                mMessageInfo.len);

            if (haveHandles) {
                if (ancillaryFds != nullptr) {
                    ancillaryFds->reserve(ancillaryFds->size() + mMessageInfo.num_handles);
                    for (size_t i = 0; i < mMessageInfo.num_handles; i++) {
                        ancillaryFds->emplace_back(base::unique_fd(msgHandles[i]));
                    }

                    // Clear the saved number of handles so we don't accidentally
                    // read them multiple times
                    mMessageInfo.num_handles = 0;
                    haveHandles = false;
                } else {
                    ALOGE("Received unexpected handles %" PRIu32, mMessageInfo.num_handles);
                    // It should be safe to continue here. We could abort, but then
                    // peers could DoS us by sending messages with handles in them.
                    // Close the handles since we are ignoring them.
                    for (size_t i = 0; i < mMessageInfo.num_handles; i++) {
                        ::close(msgHandles[i]);
                    }
                }
            }

            // Release the message if all of it has been read
            if (mMessageOffset == mMessageInfo.len) {
                releaseMessage();
Loading