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

Commit 438cce8a authored by Steven Moreland's avatar Steven Moreland
Browse files

libbinder: RPC avoid copy of transaction data

The socket code here needs a lot more optimization/analysis, but using
setIpcDataReference here is important so that we know internally whether
a Parcel is owned or not. This will allow for stronger checks in markFor*
functions which control the Parcel format.

Bug: 167966510
Test: binderRpcTest
Change-Id: Id2b0fc02972936f3e3b7382e7b56f7631a621e97
parent e8fa8e34
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -2100,6 +2100,9 @@ size_t Parcel::ipcObjectsCount() const
void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
    const binder_size_t* objects, size_t objectsCount, release_func relFunc)
{
    // this code uses 'mOwner == nullptr' to understand whether it owns memory
    LOG_ALWAYS_FATAL_IF(relFunc == nullptr, "must provide cleanup function");

    freeData();

    mData = const_cast<uint8_t*>(data);
+18 −4
Original line number Diff line number Diff line
@@ -312,7 +312,7 @@ status_t RpcState::transact(const base::unique_fd& fd, const RpcAddress& address
    return waitForReply(fd, connection, reply);
}

static void cleanup_data(Parcel* p, const uint8_t* data, size_t dataSize,
static void cleanup_reply_data(Parcel* p, const uint8_t* data, size_t dataSize,
                               const binder_size_t* objects, size_t objectsCount) {
    (void)p;
    delete[] const_cast<uint8_t*>(data - offsetof(RpcWireReply, data));
@@ -351,7 +351,7 @@ status_t RpcState::waitForReply(const base::unique_fd& fd, const sp<RpcConnectio
    if (rpcReply->status != OK) return rpcReply->status;

    reply->ipcSetDataReference(rpcReply->data, command.bodySize - offsetof(RpcWireReply, data),
                               nullptr, 0, cleanup_data);
                               nullptr, 0, cleanup_reply_data);

    reply->markForRpc(connection);

@@ -427,6 +427,15 @@ status_t RpcState::processTransact(const base::unique_fd& fd, const sp<RpcConnec
    return processTransactInternal(fd, connection, std::move(transactionData));
}

static void do_nothing_to_transact_data(Parcel* p, const uint8_t* data, size_t dataSize,
                                        const binder_size_t* objects, size_t objectsCount) {
    (void)p;
    (void)data;
    (void)dataSize;
    (void)objects;
    (void)objectsCount;
}

status_t RpcState::processTransactInternal(const base::unique_fd& fd,
                                           const sp<RpcConnection>& connection,
                                           std::vector<uint8_t>&& transactionData) {
@@ -490,7 +499,12 @@ status_t RpcState::processTransactInternal(const base::unique_fd& fd,
    }

    Parcel data;
    data.setData(transaction->data, transactionData.size() - offsetof(RpcWireTransaction, data));
    // transaction->data is owned by this function. Parcel borrows this data and
    // only holds onto it for the duration of this function call. Parcel will be
    // deleted before the 'transactionData' object.
    data.ipcSetDataReference(transaction->data,
                             transactionData.size() - offsetof(RpcWireTransaction, data),
                             nullptr /*object*/, 0 /*objectCount*/, do_nothing_to_transact_data);
    data.markForRpc(connection);

    Parcel reply;