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

Commit 8a74190b authored by David Brazdil's avatar David Brazdil
Browse files

rpc_binder: Properly shut down on socketpair() EOF

FdTrigger::triggerablePoll returns OK on POLLIN (higher priority)
and DEAD_OBJECT on POLLHUP (lower priority). Unlike INET or vsock,
socketpair() sockets trigger POLLIN|POLLHUP on EOF and EOF is detected
by recvmsg() returning zero bytes.

Adjust the server accept loop to take this into account and correctly
break out of the loop.

Bug: 250685929
Test: cleanly shut down UDS bootstrap RpcServer
Change-Id: I56d6a67373f16b5b1bdc167de94a7252bedca8e2
parent 8a1a5f8d
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -204,11 +204,15 @@ status_t RpcServer::recvmsgSocketConnection(const RpcServer& server, RpcTranspor
    iovec iov{&zero, sizeof(zero)};
    std::vector<std::variant<base::unique_fd, base::borrowed_fd>> fds;

    if (receiveMessageFromSocket(server.mServer, &iov, 1, &fds) < 0) {
    ssize_t num_bytes = receiveMessageFromSocket(server.mServer, &iov, 1, &fds);
    if (num_bytes < 0) {
        int savedErrno = errno;
        ALOGE("Failed recvmsg: %s", strerror(savedErrno));
        return -savedErrno;
    }
    if (num_bytes == 0) {
        return DEAD_OBJECT;
    }
    if (fds.size() != 1) {
        ALOGE("Expected exactly one fd from recvmsg, got %zu", fds.size());
        return -EINVAL;
@@ -243,7 +247,10 @@ void RpcServer::join() {
        socklen_t addrLen = addr.size();

        RpcTransportFd clientSocket;
        if (mAcceptFn(*this, &clientSocket) != OK) {
        if ((status = mAcceptFn(*this, &clientSocket)) != OK) {
            if (status == DEAD_OBJECT)
                break;
            else
                continue;
        }