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

Commit 8b1701f4 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes Id6f98191,Id9430ca8,Idde11124

* changes:
  libbinder: Print the iov number in RPC log messages
  libbinder: Support unaligned reads/writes in Parcel.cpp
  libbinder: Return status_t from RpcTransport::peek()
parents b8ba6e9c 0a692353
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -1584,6 +1584,7 @@ status_t Parcel::readOutVectorSizeWithCheck(size_t elmSize, int32_t* size) const
template<class T>
status_t Parcel::readAligned(T *pArg) const {
    static_assert(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
    static_assert(std::is_trivially_copyable_v<T>);

    if ((mDataPos+sizeof(T)) <= mDataSize) {
        if (mObjectsSize > 0) {
@@ -1595,9 +1596,8 @@ status_t Parcel::readAligned(T *pArg) const {
            }
        }

        const void* data = mData+mDataPos;
        memcpy(pArg, mData + mDataPos, sizeof(T));
        mDataPos += sizeof(T);
        *pArg =  *reinterpret_cast<const T*>(data);
        return NO_ERROR;
    } else {
        return NOT_ENOUGH_DATA;
@@ -1617,10 +1617,11 @@ T Parcel::readAligned() const {
template<class T>
status_t Parcel::writeAligned(T val) {
    static_assert(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
    static_assert(std::is_trivially_copyable_v<T>);

    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
restart_write:
        *reinterpret_cast<T*>(mData+mDataPos) = val;
        memcpy(mData + mDataPos, &val, sizeof(val));
        return finishWrite(sizeof(val));
    }

+12 −4
Original line number Diff line number Diff line
@@ -313,7 +313,8 @@ status_t RpcState::rpcSend(const sp<RpcSession::RpcConnection>& connection,
                           const sp<RpcSession>& session, const char* what, iovec* iovs, int niovs,
                           const std::function<status_t()>& altPoll) {
    for (int i = 0; i < niovs; i++) {
        LOG_RPC_DETAIL("Sending %s on RpcTransport %p: %s", what, connection->rpcTransport.get(),
        LOG_RPC_DETAIL("Sending %s (part %d of %d) on RpcTransport %p: %s",
                       what, i + 1, niovs, connection->rpcTransport.get(),
                       android::base::HexString(iovs[i].iov_base, iovs[i].iov_len).c_str());
    }

@@ -343,7 +344,8 @@ status_t RpcState::rpcRec(const sp<RpcSession::RpcConnection>& connection,
    }

    for (int i = 0; i < niovs; i++) {
        LOG_RPC_DETAIL("Received %s on RpcTransport %p: %s", what, connection->rpcTransport.get(),
        LOG_RPC_DETAIL("Received %s (part %d of %d) on RpcTransport %p: %s",
                       what, i + 1, niovs, connection->rpcTransport.get(),
                       android::base::HexString(iovs[i].iov_base, iovs[i].iov_len).c_str());
    }
    return OK;
@@ -660,8 +662,14 @@ status_t RpcState::getAndExecuteCommand(const sp<RpcSession::RpcConnection>& con
status_t RpcState::drainCommands(const sp<RpcSession::RpcConnection>& connection,
                                 const sp<RpcSession>& session, CommandType type) {
    uint8_t buf;
    while (connection->rpcTransport->peek(&buf, sizeof(buf)).value_or(0) > 0) {
        status_t status = getAndExecuteCommand(connection, session, type);
    while (true) {
        size_t num_bytes;
        status_t status = connection->rpcTransport->peek(&buf, sizeof(buf), &num_bytes);
        if (status == WOULD_BLOCK) break;
        if (status != OK) return status;
        if (!num_bytes) break;

        status = getAndExecuteCommand(connection, session, type);
        if (status != OK) return status;
    }
    return OK;
+11 −6
Original line number Diff line number Diff line
@@ -24,9 +24,6 @@
#include "FdTrigger.h"
#include "RpcState.h"

using android::base::ErrnoError;
using android::base::Result;

namespace android {

namespace {
@@ -35,12 +32,20 @@ namespace {
class RpcTransportRaw : public RpcTransport {
public:
    explicit RpcTransportRaw(android::base::unique_fd socket) : mSocket(std::move(socket)) {}
    Result<size_t> peek(void *buf, size_t size) override {
    status_t peek(void* buf, size_t size, size_t* out_size) override {
        ssize_t ret = TEMP_FAILURE_RETRY(::recv(mSocket.get(), buf, size, MSG_PEEK));
        if (ret < 0) {
            return ErrnoError() << "recv(MSG_PEEK)";
            int savedErrno = errno;
            if (savedErrno == EAGAIN || savedErrno == EWOULDBLOCK) {
                return WOULD_BLOCK;
            }
        return ret;

            LOG_RPC_DETAIL("RpcTransport peek(): %s", strerror(savedErrno));
            return -savedErrno;
        }

        *out_size = static_cast<size_t>(ret);
        return OK;
    }

    template <typename SendOrReceive>
+24 −19
Original line number Diff line number Diff line
@@ -37,10 +37,6 @@
#define LOG_TLS_DETAIL(...) ALOGV(__VA_ARGS__) // for type checking
#endif

using android::base::ErrnoError;
using android::base::Error;
using android::base::Result;

namespace android {
namespace {

@@ -165,17 +161,8 @@ public:
        return ret;
    }

    // |sslError| should be from Ssl::getError().
    // If |sslError| is WANT_READ / WANT_WRITE, poll for POLLIN / POLLOUT respectively. Otherwise
    // return error. Also return error if |fdTrigger| is triggered before or during poll().
    status_t pollForSslError(android::base::borrowed_fd fd, int sslError, FdTrigger* fdTrigger,
                             const char* fnString, int additionalEvent,
                             const std::function<status_t()>& altPoll) {
    status_t toStatus(int sslError, const char* fnString) {
        switch (sslError) {
            case SSL_ERROR_WANT_READ:
                return handlePoll(POLLIN | additionalEvent, fd, fdTrigger, fnString, altPoll);
            case SSL_ERROR_WANT_WRITE:
                return handlePoll(POLLOUT | additionalEvent, fd, fdTrigger, fnString, altPoll);
            case SSL_ERROR_SYSCALL: {
                auto queue = toString();
                LOG_TLS_DETAIL("%s(): %s. Treating as DEAD_OBJECT. Error queue: %s", fnString,
@@ -191,6 +178,22 @@ public:
        }
    }

    // |sslError| should be from Ssl::getError().
    // If |sslError| is WANT_READ / WANT_WRITE, poll for POLLIN / POLLOUT respectively. Otherwise
    // return error. Also return error if |fdTrigger| is triggered before or during poll().
    status_t pollForSslError(android::base::borrowed_fd fd, int sslError, FdTrigger* fdTrigger,
                             const char* fnString, int additionalEvent,
                             const std::function<status_t()>& altPoll) {
        switch (sslError) {
            case SSL_ERROR_WANT_READ:
                return handlePoll(POLLIN | additionalEvent, fd, fdTrigger, fnString, altPoll);
            case SSL_ERROR_WANT_WRITE:
                return handlePoll(POLLOUT | additionalEvent, fd, fdTrigger, fnString, altPoll);
            default:
                return toStatus(sslError, fnString);
        }
    }

private:
    bool mHandled = false;

@@ -274,7 +277,7 @@ class RpcTransportTls : public RpcTransport {
public:
    RpcTransportTls(android::base::unique_fd socket, Ssl ssl)
          : mSocket(std::move(socket)), mSsl(std::move(ssl)) {}
    Result<size_t> peek(void* buf, size_t size) override;
    status_t peek(void* buf, size_t size, size_t* out_size) override;
    status_t interruptableWriteFully(FdTrigger* fdTrigger, iovec* iovs, int niovs,
                                     const std::function<status_t()>& altPoll) override;
    status_t interruptableReadFully(FdTrigger* fdTrigger, iovec* iovs, int niovs,
@@ -286,7 +289,7 @@ private:
};

// Error code is errno.
Result<size_t> RpcTransportTls::peek(void* buf, size_t size) {
status_t RpcTransportTls::peek(void* buf, size_t size, size_t* out_size) {
    size_t todo = std::min<size_t>(size, std::numeric_limits<int>::max());
    auto [ret, errorQueue] = mSsl.call(SSL_peek, buf, static_cast<int>(todo));
    if (ret < 0) {
@@ -294,13 +297,15 @@ Result<size_t> RpcTransportTls::peek(void* buf, size_t size) {
        if (err == SSL_ERROR_WANT_WRITE || err == SSL_ERROR_WANT_READ) {
            // Seen EAGAIN / EWOULDBLOCK on recv(2) / send(2).
            // Like RpcTransportRaw::peek(), don't handle it here.
            return Error(EWOULDBLOCK) << "SSL_peek(): " << errorQueue.toString();
            errorQueue.clear();
            return WOULD_BLOCK;
        }
        return Error() << "SSL_peek(): " << errorQueue.toString();
        return errorQueue.toStatus(err, "SSL_peek");
    }
    errorQueue.clear();
    LOG_TLS_DETAIL("TLS: Peeked %d bytes!", ret);
    return ret;
    *out_size = static_cast<size_t>(ret);
    return OK;
}

status_t RpcTransportTls::interruptableWriteFully(FdTrigger* fdTrigger, iovec* iovs, int niovs,
+1 −2
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@
#include <memory>
#include <string>

#include <android-base/result.h>
#include <android-base/unique_fd.h>
#include <utils/Errors.h>

@@ -41,7 +40,7 @@ public:
    virtual ~RpcTransport() = default;

    // replacement of ::recv(MSG_PEEK). Error code may not be set if TLS is enabled.
    [[nodiscard]] virtual android::base::Result<size_t> peek(void *buf, size_t size) = 0;
    [[nodiscard]] virtual status_t peek(void *buf, size_t size, size_t *out_size) = 0;

    /**
     * Read (or write), but allow to be interrupted by a trigger.
Loading