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

Commit a9cca9cb authored by Andrei Homescu's avatar Andrei Homescu
Browse files

libbinder: build option to disable the kernel IPC, part 2/2

Use BINDER_KERNEL_IPC to disable all code that
uses flat_binder_object in Parcel.cpp.

Bug: 224644083
Test: m
Change-Id: I1f676dbfb464fc0c5eaa6b5266b7af1dabe984e1
parent 32150288
Loading
Loading
Loading
Loading
+107 −4
Original line number Diff line number Diff line
@@ -20,15 +20,14 @@
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <linux/sched.h>
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <unistd.h>

#include <binder/Binder.h>
@@ -52,7 +51,22 @@
#include "RpcState.h"
#include "Static.h"
#include "Utils.h"

// A lot of code in this file uses definitions from the
// Linux kernel header for Binder <linux/android/binder.h>
// which is included indirectly via "binder_module.h".
// Non-Linux OSes do not have that header, so libbinder should be
// built for those targets without kernel binder support, i.e.,
// without BINDER_WITH_KERNEL_IPC. For this reason, all code in this
// file that depends on kernel binder, including the header itself,
// is conditional on BINDER_WITH_KERNEL_IPC.
#ifdef BINDER_WITH_KERNEL_IPC
#include <linux/sched.h>
#include "binder_module.h"
#else  // BINDER_WITH_KERNEL_IPC
// Needed by {read,write}Pointer
typedef uintptr_t binder_uintptr_t;
#endif // BINDER_WITH_KERNEL_IPC

#define LOG_REFS(...)
// #define LOG_REFS(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
@@ -100,6 +114,7 @@ enum {
    BLOB_ASHMEM_MUTABLE = 2,
};

#ifdef BINDER_WITH_KERNEL_IPC
static void acquire_object(const sp<ProcessState>& proc, const flat_binder_object& obj,
                           const void* who) {
    switch (obj.hdr.type) {
@@ -152,6 +167,7 @@ static void release_object(const sp<ProcessState>& proc, const flat_binder_objec

    ALOGE("Invalid object type 0x%08x", obj.hdr.type);
}
#endif // BINDER_WITH_KERNEL_IPC

static int toRawFd(const std::variant<base::unique_fd, base::borrowed_fd>& v) {
    return std::visit([](const auto& fd) { return fd.get(); }, v);
@@ -183,9 +199,11 @@ status_t Parcel::finishUnflattenBinder(
    return OK;
}

#ifdef BINDER_WITH_KERNEL_IPC
static constexpr inline int schedPolicyMask(int policy, int priority) {
    return (priority & FLAT_BINDER_FLAG_PRIORITY_MASK) | ((policy & 3) << FLAT_BINDER_FLAG_SCHED_POLICY_SHIFT);
}
#endif // BINDER_WITH_KERNEL_IPC

status_t Parcel::flattenBinder(const sp<IBinder>& binder) {
    BBinder* local = nullptr;
@@ -210,6 +228,7 @@ status_t Parcel::flattenBinder(const sp<IBinder>& binder) {
        return finishFlattenBinder(binder);
    }

#ifdef BINDER_WITH_KERNEL_IPC
    flat_binder_object obj;

    int schedBits = 0;
@@ -266,6 +285,10 @@ status_t Parcel::flattenBinder(const sp<IBinder>& binder) {
    if (status != OK) return status;

    return finishFlattenBinder(binder);
#else  // BINDER_WITH_KERNEL_IPC
    LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
    return INVALID_OPERATION;
#endif // BINDER_WITH_KERNEL_IPC
}

status_t Parcel::unflattenBinder(sp<IBinder>* out) const
@@ -295,6 +318,7 @@ status_t Parcel::unflattenBinder(sp<IBinder>* out) const
        return finishUnflattenBinder(binder, out);
    }

#ifdef BINDER_WITH_KERNEL_IPC
    const flat_binder_object* flat = readObject(false);

    if (flat) {
@@ -312,6 +336,10 @@ status_t Parcel::unflattenBinder(sp<IBinder>* out) const
        }
    }
    return BAD_TYPE;
#else  // BINDER_WITH_KERNEL_IPC
    LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
    return INVALID_OPERATION;
#endif // BINDER_WITH_KERNEL_IPC
}

// ---------------------------------------------------------------------------
@@ -475,6 +503,7 @@ status_t Parcel::appendFrom(const Parcel* parcel, size_t offset, size_t len) {

    err = NO_ERROR;

#ifdef BINDER_WITH_KERNEL_IPC
    if (auto* kernelFields = maybeKernelFields()) {
        auto* otherKernelFields = parcel->maybeKernelFields();
        LOG_ALWAYS_FATAL_IF(otherKernelFields == nullptr);
@@ -593,6 +622,7 @@ status_t Parcel::appendFrom(const Parcel* parcel, size_t offset, size_t len) {
            }
        }
    }
#endif // BINDER_WITH_KERNEL_IPC

    return err;
}
@@ -658,6 +688,7 @@ bool Parcel::hasFileDescriptors() const
std::vector<sp<IBinder>> Parcel::debugReadAllStrongBinders() const {
    std::vector<sp<IBinder>> ret;

#ifdef BINDER_WITH_KERNEL_IPC
    const auto* kernelFields = maybeKernelFields();
    if (kernelFields == nullptr) {
        return ret;
@@ -677,6 +708,8 @@ std::vector<sp<IBinder>> Parcel::debugReadAllStrongBinders() const {
    }

    setDataPosition(initPosition);
#endif // BINDER_WITH_KERNEL_IPC

    return ret;
}

@@ -684,6 +717,7 @@ std::vector<int> Parcel::debugReadAllFileDescriptors() const {
    std::vector<int> ret;

    if (const auto* kernelFields = maybeKernelFields()) {
#ifdef BINDER_WITH_KERNEL_IPC
        size_t initPosition = dataPosition();
        for (size_t i = 0; i < kernelFields->mObjectsSize; i++) {
            binder_size_t offset = kernelFields->mObjects[i];
@@ -698,6 +732,9 @@ std::vector<int> Parcel::debugReadAllFileDescriptors() const {
            ret.push_back(fd);
        }
        setDataPosition(initPosition);
#else
        LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
#endif
    } else if (const auto* rpcFields = maybeRpcFields(); rpcFields && rpcFields->mFds) {
        for (const auto& fd : *rpcFields->mFds) {
            ret.push_back(toRawFd(fd));
@@ -719,6 +756,7 @@ status_t Parcel::hasFileDescriptorsInRange(size_t offset, size_t len, bool* resu
    }
    *result = false;
    if (const auto* kernelFields = maybeKernelFields()) {
#ifdef BINDER_WITH_KERNEL_IPC
        for (size_t i = 0; i < kernelFields->mObjectsSize; i++) {
            size_t pos = kernelFields->mObjects[i];
            if (pos < offset) continue;
@@ -736,6 +774,10 @@ status_t Parcel::hasFileDescriptorsInRange(size_t offset, size_t len, bool* resu
                break;
            }
        }
#else
        LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
        return INVALID_OPERATION;
#endif // BINDER_WITH_KERNEL_IPC
    } else if (const auto* rpcFields = maybeRpcFields()) {
        for (uint32_t pos : rpcFields->mObjectPositions) {
            if (offset <= pos && pos < limit) {
@@ -788,6 +830,7 @@ void Parcel::updateWorkSourceRequestHeaderPosition() const {
    }
}

#ifdef BINDER_WITH_KERNEL_IPC
#if defined(__ANDROID_VNDK__)
constexpr int32_t kHeader = B_PACK_CHARS('V', 'N', 'D', 'R');
#elif defined(__ANDROID_RECOVERY__)
@@ -795,6 +838,7 @@ constexpr int32_t kHeader = B_PACK_CHARS('R', 'E', 'C', 'O');
#else
constexpr int32_t kHeader = B_PACK_CHARS('S', 'Y', 'S', 'T');
#endif
#endif // BINDER_WITH_KERNEL_IPC

// Write RPC headers.  (previously just the interface token)
status_t Parcel::writeInterfaceToken(const String16& interface)
@@ -804,12 +848,17 @@ status_t Parcel::writeInterfaceToken(const String16& interface)

status_t Parcel::writeInterfaceToken(const char16_t* str, size_t len) {
    if (auto* kernelFields = maybeKernelFields()) {
#ifdef BINDER_WITH_KERNEL_IPC
        const IPCThreadState* threadState = IPCThreadState::self();
        writeInt32(threadState->getStrictModePolicy() | STRICT_MODE_PENALTY_GATHER);
        updateWorkSourceRequestHeaderPosition();
        writeInt32(threadState->shouldPropagateWorkSource() ? threadState->getCallingWorkSourceUid()
                                                            : IPCThreadState::kUnsetWorkSource);
        writeInt32(kHeader);
#else  // BINDER_WITH_KERNEL_IPC
        LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
        return INVALID_OPERATION;
#endif // BINDER_WITH_KERNEL_IPC
    }

    // currently the interface identification token is just its name as a string
@@ -866,6 +915,7 @@ bool Parcel::enforceInterface(const char16_t* interface,
                              IPCThreadState* threadState) const
{
    if (auto* kernelFields = maybeKernelFields()) {
#ifdef BINDER_WITH_KERNEL_IPC
        // StrictModePolicy.
        int32_t strictPolicy = readInt32();
        if (threadState == nullptr) {
@@ -891,6 +941,11 @@ bool Parcel::enforceInterface(const char16_t* interface,
                  header);
            return false;
        }
#else  // BINDER_WITH_KERNEL_IPC
        LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
        (void)threadState;
        return false;
#endif // BINDER_WITH_KERNEL_IPC
    }

    // Interface descriptor.
@@ -1401,6 +1456,7 @@ status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership) {
        }
    }

#ifdef BINDER_WITH_KERNEL_IPC
    flat_binder_object obj;
    obj.hdr.type = BINDER_TYPE_FD;
    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
@@ -1408,6 +1464,12 @@ status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership) {
    obj.handle = fd;
    obj.cookie = takeOwnership ? 1 : 0;
    return writeObject(obj, true);
#else  // BINDER_WITH_KERNEL_IPC
    LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
    (void)fd;
    (void)takeOwnership;
    return INVALID_OPERATION;
#endif // BINDER_WITH_KERNEL_IPC
}

status_t Parcel::writeDupFileDescriptor(int fd)
@@ -1561,6 +1623,7 @@ status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
    auto* kernelFields = maybeKernelFields();
    LOG_ALWAYS_FATAL_IF(kernelFields == nullptr, "Can't write flat_binder_object to RPC Parcel");

#ifdef BINDER_WITH_KERNEL_IPC
    const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
    const bool enoughObjects = kernelFields->mObjectsSize < kernelFields->mObjectsCapacity;
    if (enoughData && enoughObjects) {
@@ -1603,6 +1666,12 @@ restart_write:
    }

    goto restart_write;
#else  // BINDER_WITH_KERNEL_IPC
    LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
    (void)val;
    (void)nullMetaData;
    return INVALID_OPERATION;
#endif // BINDER_WITH_KERNEL_IPC
}

status_t Parcel::writeNoException()
@@ -1620,6 +1689,7 @@ status_t Parcel::validateReadData(size_t upperBound) const
        return OK;
    }

#ifdef BINDER_WITH_KERNEL_IPC
    // Don't allow non-object reads on object data
    if (kernelFields->mObjectsSorted || kernelFields->mObjectsSize <= 1) {
    data_sorted:
@@ -1672,6 +1742,10 @@ data_unsorted:
    kernelFields->mNextObjectHint = 0;
    kernelFields->mObjectsSorted = true;
    goto data_sorted;
#else  // BINDER_WITH_KERNEL_IPC
    (void)upperBound;
    return NO_ERROR;
#endif // BINDER_WITH_KERNEL_IPC
}

status_t Parcel::read(void* outData, size_t len) const
@@ -2164,6 +2238,7 @@ int Parcel::readFileDescriptor() const {
        return toRawFd(rpcFields->mFds->at(fdIndex));
    }

#ifdef BINDER_WITH_KERNEL_IPC
    const flat_binder_object* flat = readObject(true);

    if (flat && flat->hdr.type == BINDER_TYPE_FD) {
@@ -2171,6 +2246,10 @@ int Parcel::readFileDescriptor() const {
    }

    return BAD_TYPE;
#else  // BINDER_WITH_KERNEL_IPC
    LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
    return INVALID_OPERATION;
#endif // BINDER_WITH_KERNEL_IPC
}

int Parcel::readParcelFileDescriptor() const {
@@ -2326,6 +2405,8 @@ status_t Parcel::read(FlattenableHelperInterface& val) const

    return err;
}

#ifdef BINDER_WITH_KERNEL_IPC
const flat_binder_object* Parcel::readObject(bool nullMetaData) const
{
    const auto* kernelFields = maybeKernelFields();
@@ -2391,9 +2472,11 @@ const flat_binder_object* Parcel::readObject(bool nullMetaData) const
    }
    return nullptr;
}
#endif // BINDER_WITH_KERNEL_IPC

void Parcel::closeFileDescriptors() {
    if (auto* kernelFields = maybeKernelFields()) {
#ifdef BINDER_WITH_KERNEL_IPC
        size_t i = kernelFields->mObjectsSize;
        if (i > 0) {
            // ALOGI("Closing file descriptors for %zu objects...", i);
@@ -2407,6 +2490,9 @@ void Parcel::closeFileDescriptors() {
                close(flat->handle);
            }
        }
#else  // BINDER_WITH_KERNEL_IPC
        LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
#endif // BINDER_WITH_KERNEL_IPC
    } else if (auto* rpcFields = maybeRpcFields()) {
        rpcFields->mFds.reset();
    }
@@ -2454,6 +2540,7 @@ void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize, const bin
    kernelFields->mObjectsSize = kernelFields->mObjectsCapacity = objectsCount;
    mOwner = relFunc;

#ifdef BINDER_WITH_KERNEL_IPC
    binder_size_t minOffset = 0;
    for (size_t i = 0; i < kernelFields->mObjectsSize; i++) {
        binder_size_t offset = kernelFields->mObjects[i];
@@ -2484,6 +2571,10 @@ void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize, const bin
        minOffset = offset + sizeof(flat_binder_object);
    }
    scanForFds();
#else  // BINDER_WITH_KERNEL_IPC
    LOG_ALWAYS_FATAL_IF(objectsCount != 0,
                        "Non-zero objects count passed to Parcel with kernel driver disabled");
#endif // BINDER_WITH_KERNEL_IPC
}

status_t Parcel::rpcSetDataReference(
@@ -2534,6 +2625,7 @@ void Parcel::print(TextOutput& to, uint32_t /*flags*/) const
    } else if (dataSize() > 0) {
        const uint8_t* DATA = data();
        to << indent << HexDump(DATA, dataSize()) << dedent;
#ifdef BINDER_WITH_KERNEL_IPC
        if (const auto* kernelFields = maybeKernelFields()) {
            const binder_size_t* OBJS = kernelFields->mObjects;
            const size_t N = objectsCount();
@@ -2545,6 +2637,7 @@ void Parcel::print(TextOutput& to, uint32_t /*flags*/) const
                   << TypeCode(flat->hdr.type & 0x7f7f7f00) << " = " << flat->binder;
            }
        }
#endif // BINDER_WITH_KERNEL_IPC
    } else {
        to << "NULL";
    }
@@ -2559,6 +2652,7 @@ void Parcel::releaseObjects()
        return;
    }

#ifdef BINDER_WITH_KERNEL_IPC
    size_t i = kernelFields->mObjectsSize;
    if (i == 0) {
        return;
@@ -2571,6 +2665,7 @@ void Parcel::releaseObjects()
        const flat_binder_object* flat = reinterpret_cast<flat_binder_object*>(data + objects[i]);
        release_object(proc, *flat, this);
    }
#endif // BINDER_WITH_KERNEL_IPC
}

void Parcel::acquireObjects()
@@ -2580,6 +2675,7 @@ void Parcel::acquireObjects()
        return;
    }

#ifdef BINDER_WITH_KERNEL_IPC
    size_t i = kernelFields->mObjectsSize;
    if (i == 0) {
        return;
@@ -2592,6 +2688,7 @@ void Parcel::acquireObjects()
        const flat_binder_object* flat = reinterpret_cast<flat_binder_object*>(data + objects[i]);
        acquire_object(proc, *flat, this);
    }
#endif // BINDER_WITH_KERNEL_IPC
}

void Parcel::freeData()
@@ -2813,6 +2910,7 @@ status_t Parcel::continueWrite(size_t desired)

    } else if (mData) {
        if (kernelFields && objectsSize < kernelFields->mObjectsSize) {
#ifdef BINDER_WITH_KERNEL_IPC
            // Need to release refs on any objects we are dropping.
            const sp<ProcessState> proc(ProcessState::self());
            for (size_t i = objectsSize; i < kernelFields->mObjectsSize; i++) {
@@ -2841,6 +2939,9 @@ status_t Parcel::continueWrite(size_t desired)
            kernelFields->mObjectsSize = objectsSize;
            kernelFields->mNextObjectHint = 0;
            kernelFields->mObjectsSorted = false;
#else  // BINDER_WITH_KERNEL_IPC
            LOG_ALWAYS_FATAL("Non-zero numObjects for RPC Parcel");
#endif // BINDER_WITH_KERNEL_IPC
        }
        if (rpcFields) {
            if (status_t status = truncateRpcObjects(objectsSize); status != OK) {
@@ -2958,6 +3059,7 @@ void Parcel::scanForFds() const {
    kernelFields->mFdsKnown = true;
}

#ifdef BINDER_WITH_KERNEL_IPC
size_t Parcel::getBlobAshmemSize() const
{
    // This used to return the size of all blobs that were written to ashmem, now we're returning
@@ -2990,6 +3092,7 @@ size_t Parcel::getOpenAshmemSize() const
    }
    return openAshmemSize;
}
#endif // BINDER_WITH_KERNEL_IPC

// --- Parcel::Blob ---