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

Commit b675ffe4 authored by Yifan Hong's avatar Yifan Hong
Browse files

binder: RPC uses non-blocking sockets.

With TLS, even though poll() may have returned for an FD,
there may not be a complete packet available, so I/O operations
within libssl may block and not interruptible by the shutdown
trigger.

Hence, always use non-blocking sockets.

Test: binderRpcTest
Bug: 195683291
Change-Id: I372e8c3bf010c672b1c4b9f7cb5b789ca20c9480
parent 8c950421
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -168,7 +168,7 @@ void RpcServer::join() {
    status_t status;
    while ((status = mShutdownTrigger->triggerablePoll(mServer, POLLIN)) == OK) {
        unique_fd clientFd(TEMP_FAILURE_RETRY(
                accept4(mServer.get(), nullptr, nullptr /*length*/, SOCK_CLOEXEC)));
                accept4(mServer.get(), nullptr, nullptr /*length*/, SOCK_CLOEXEC | SOCK_NONBLOCK)));

        if (clientFd < 0) {
            ALOGE("Could not accept4 socket: %s", strerror(errno));
@@ -388,8 +388,8 @@ status_t RpcServer::setupSocketServer(const RpcSocketAddress& addr) {
    LOG_RPC_DETAIL("Setting up socket server %s", addr.toString().c_str());
    LOG_ALWAYS_FATAL_IF(hasServer(), "Each RpcServer can only have one server.");

    unique_fd serverFd(
            TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)));
    unique_fd serverFd(TEMP_FAILURE_RETRY(
            socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)));
    if (serverFd == -1) {
        int savedErrno = errno;
        ALOGE("Could not create socket: %s", strerror(savedErrno));
+7 −2
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@
#include "RpcSocketAddress.h"
#include "RpcState.h"
#include "RpcWireFormat.h"
#include "Utils.h"

#ifdef __GLIBC__
extern "C" pid_t gettid();
@@ -134,6 +135,10 @@ status_t RpcSession::setupPreconnectedClient(unique_fd fd, std::function<unique_
            fd = request();
            if (!fd.ok()) return BAD_VALUE;
        }
        if (auto res = setNonBlocking(fd); !res.ok()) {
            ALOGE("setupPreconnectedClient: %s", res.error().message().c_str());
            return res.error().code() == 0 ? UNKNOWN_ERROR : -res.error().code();
        }
        return initAndAddConnection(std::move(fd), sessionId, incoming);
    });
}
@@ -470,8 +475,8 @@ status_t RpcSession::setupOneSocketConnection(const RpcSocketAddress& addr,
    for (size_t tries = 0; tries < 5; tries++) {
        if (tries > 0) usleep(10000);

        unique_fd serverFd(
                TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)));
        unique_fd serverFd(TEMP_FAILURE_RETRY(
                socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)));
        if (serverFd == -1) {
            int savedErrno = errno;
            ALOGE("Could not create socket at %s: %s", addr.toString().c_str(),
+1 −1
Original line number Diff line number Diff line
@@ -50,7 +50,7 @@ public:
        return ret;
    }
    Result<size_t> peek(void *buf, size_t size) override {
        ssize_t ret = TEMP_FAILURE_RETRY(::recv(mSocket.get(), buf, size, MSG_PEEK | MSG_DONTWAIT));
        ssize_t ret = TEMP_FAILURE_RETRY(::recv(mSocket.get(), buf, size, MSG_PEEK));
        if (ret < 0) {
            return ErrnoError() << "recv(MSG_PEEK)";
        }
+15 −1
Original line number Diff line number Diff line
@@ -18,10 +18,24 @@

#include <string.h>

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

namespace android {

void zeroMemory(uint8_t* data, size_t size) {
    memset(data, 0, size);
}

Result<void> setNonBlocking(android::base::borrowed_fd fd) {
    int flags = TEMP_FAILURE_RETRY(fcntl(fd.get(), F_GETFL));
    if (flags == -1) {
        return ErrnoError() << "Could not get flags for fd";
    }
    if (int ret = TEMP_FAILURE_RETRY(fcntl(fd.get(), F_SETFL, flags | O_NONBLOCK)); ret == -1) {
        return ErrnoError() << "Could not set non-blocking flag for fd";
    }
    return {};
}

} // namespace android
+5 −0
Original line number Diff line number Diff line
@@ -17,9 +17,14 @@
#include <cstdint>
#include <stddef.h>

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

namespace android {

// avoid optimizations
void zeroMemory(uint8_t* data, size_t size);

android::base::Result<void> setNonBlocking(android::base::borrowed_fd fd);

}   // namespace android