libbinder: RPC avoid abort on too big allocations
We may want some more heuristic checks here, since allocations that are
just barely too big may interrupt the operations of other threads that
can't handle failing allocations, but this is a start so that too-big
allocations won't cause an abort.
Bug: 182938024
Test: binderRpcTest + running WIP fuzzer
Change-Id: Id9f1b63962cd22b7c799b14e595c47ea8628354f
diff --git a/libs/binder/RpcState.h b/libs/binder/RpcState.h
index 3f3eb1c..83d0344 100644
--- a/libs/binder/RpcState.h
+++ b/libs/binder/RpcState.h
@@ -21,6 +21,7 @@
#include <binder/RpcSession.h>
#include <map>
+#include <optional>
#include <queue>
namespace android {
@@ -100,6 +101,20 @@
*/
void terminate();
+ // alternative to std::vector<uint8_t> that doesn't abort on too big of allocations
+ struct ByteVec {
+ explicit ByteVec(size_t size)
+ : mData(size > 0 ? new (std::nothrow) uint8_t[size] : nullptr), mSize(size) {}
+ bool valid() { return mSize == 0 || mData != nullptr; }
+ size_t size() { return mSize; }
+ uint8_t* data() { return mData.get(); }
+ uint8_t* release() { return mData.release(); }
+
+ private:
+ std::unique_ptr<uint8_t[]> mData;
+ size_t mSize;
+ };
+
[[nodiscard]] bool rpcSend(const base::unique_fd& fd, const char* what, const void* data,
size_t size);
[[nodiscard]] bool rpcRec(const base::unique_fd& fd, const char* what, void* data, size_t size);
@@ -113,7 +128,7 @@
const RpcWireHeader& command);
[[nodiscard]] status_t processTransactInternal(const base::unique_fd& fd,
const sp<RpcSession>& session,
- std::vector<uint8_t>&& transactionData);
+ ByteVec transactionData);
[[nodiscard]] status_t processDecStrong(const base::unique_fd& fd,
const RpcWireHeader& command);
@@ -148,7 +163,7 @@
// async transaction queue, _only_ for local binder
struct AsyncTodo {
- std::vector<uint8_t> data; // most convenient format, to move it here
+ ByteVec data;
uint64_t asyncNumber = 0;
bool operator<(const AsyncTodo& o) const {