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
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 0354382..3dccf20 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -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,12 +51,27 @@
#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__)
+// #define LOG_REFS(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOG_ALLOC(...)
-//#define LOG_ALLOC(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
+// #define LOG_ALLOC(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
// ---------------------------------------------------------------------------
@@ -100,6 +114,7 @@
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 @@
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 @@
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 @@
return finishFlattenBinder(binder);
}
+#ifdef BINDER_WITH_KERNEL_IPC
flat_binder_object obj;
int schedBits = 0;
@@ -266,6 +285,10 @@
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 @@
return finishUnflattenBinder(binder, out);
}
+#ifdef BINDER_WITH_KERNEL_IPC
const flat_binder_object* flat = readObject(false);
if (flat) {
@@ -312,6 +336,10 @@
}
}
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 @@
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 @@
}
}
}
+#endif // BINDER_WITH_KERNEL_IPC
return err;
}
@@ -658,6 +688,7 @@
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 @@
}
setDataPosition(initPosition);
+#endif // BINDER_WITH_KERNEL_IPC
+
return ret;
}
@@ -684,6 +717,7 @@
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 @@
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 @@
}
*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 @@
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 @@
}
}
+#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 @@
#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 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 @@
IPCThreadState* threadState) const
{
if (auto* kernelFields = maybeKernelFields()) {
+#ifdef BINDER_WITH_KERNEL_IPC
// StrictModePolicy.
int32_t strictPolicy = readInt32();
if (threadState == nullptr) {
@@ -891,6 +941,11 @@
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 @@
}
}
+#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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
}
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 @@
return err;
}
+
+#ifdef BINDER_WITH_KERNEL_IPC
const flat_binder_object* Parcel::readObject(bool nullMetaData) const
{
const auto* kernelFields = maybeKernelFields();
@@ -2391,9 +2472,11 @@
}
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 @@
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 @@
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 @@
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 @@
} 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 @@
<< TypeCode(flat->hdr.type & 0x7f7f7f00) << " = " << flat->binder;
}
}
+#endif // BINDER_WITH_KERNEL_IPC
} else {
to << "NULL";
}
@@ -2559,6 +2652,7 @@
return;
}
+#ifdef BINDER_WITH_KERNEL_IPC
size_t i = kernelFields->mObjectsSize;
if (i == 0) {
return;
@@ -2571,6 +2665,7 @@
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 @@
return;
}
+#ifdef BINDER_WITH_KERNEL_IPC
size_t i = kernelFields->mObjectsSize;
if (i == 0) {
return;
@@ -2592,6 +2688,7 @@
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 @@
} 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 @@
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 @@
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 @@
}
return openAshmemSize;
}
+#endif // BINDER_WITH_KERNEL_IPC
// --- Parcel::Blob ---