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

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

Merge "Trusty Binder: split large messages in RpcTransportTipcTrusty" into main

parents d12ae836 3e90a881
Loading
Loading
Loading
Loading
+60 −27
Original line number Original line Diff line number Diff line
@@ -25,6 +25,7 @@


#include "../FdTrigger.h"
#include "../FdTrigger.h"
#include "../RpcState.h"
#include "../RpcState.h"
#include "../RpcTransportUtils.h"
#include "TrustyStatus.h"
#include "TrustyStatus.h"


namespace android {
namespace android {
@@ -113,21 +114,18 @@ public:
    }
    }


    status_t interruptableWriteFully(
    status_t interruptableWriteFully(
            FdTrigger* /*fdTrigger*/, iovec* iovs, int niovs,
            FdTrigger* fdTrigger, iovec* iovs, int niovs,
            const std::optional<SmallFunction<status_t()>>& /* altPoll */,
            const std::optional<SmallFunction<status_t()>>& /* altPoll */,
            const std::vector<std::variant<unique_fd, borrowed_fd>>* ancillaryFds) override {
            const std::vector<std::variant<unique_fd, borrowed_fd>>* ancillaryFds) override {
        if (niovs < 0) {
        if (niovs < 0) {
            return BAD_VALUE;
            return BAD_VALUE;
        }
        }


        size_t size = 0;
        auto writeFn = [&](iovec* iovs, size_t niovs) -> ssize_t {
        for (int i = 0; i < niovs; i++) {
            // Collect the ancillary FDs.
            size += iovs[i].iov_len;
        }

            handle_t msgHandles[IPC_MAX_MSG_HANDLES];
            handle_t msgHandles[IPC_MAX_MSG_HANDLES];
            ipc_msg_t msg{
            ipc_msg_t msg{
                .num_iov = static_cast<uint32_t>(niovs),
                    .num_iov = 0,
                    .iov = iovs,
                    .iov = iovs,
                    .num_handles = 0,
                    .num_handles = 0,
                    .handles = nullptr,
                    .handles = nullptr,
@@ -143,15 +141,50 @@ public:
                }
                }


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


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


        return sendTrustyMsg(&msg, size);
            // Trusty currently has a message size limit, which will go away once we
            // switch to vsock. The message is reassembled on the receiving side.
            static const size_t maxMsgSize = VIRTIO_VSOCK_MSG_SIZE_LIMIT;
            size_t niovsMsg;
            size_t currSize = 0;
            size_t cutSize = 0;
            for (niovsMsg = 0; niovsMsg < (size_t)niovs; niovsMsg++) {
                if (__builtin_add_overflow(currSize, iovs[niovsMsg].iov_len, &currSize)) {
                    ALOGE("%s: iov_len add_overflow", __FUNCTION__);
                    return NO_MEMORY;
                }
                if (currSize >= maxMsgSize) {
                    // Truncate the last iov but restore it at the end
                    // so the caller can continue where we left off.
                    cutSize = currSize - maxMsgSize;
                    iovs[niovsMsg].iov_len -= cutSize;
                    niovsMsg++;
                    break;
                }
            }
            msg.num_iov = static_cast<uint32_t>(niovsMsg);

            auto rc = sendTrustyMsg(&msg, currSize - cutSize);
            if (niovsMsg > 0) {
                iovs[niovsMsg - 1].iov_len += cutSize;
            }
            if (rc == NO_ERROR) {
                return currSize - cutSize;
            } else {
                return 0;
            }
        };

        auto altPoll = []() -> status_t { return NO_ERROR; };
        return interruptableReadOrWrite(mSocket, fdTrigger, iovs, niovs, writeFn, "tipc_send",
                                        0 /* poll event, should never be used */, altPoll);
    }
    }


    status_t interruptableReadFully(
    status_t interruptableReadFully(