diff options
author | 2022-07-15 00:04:33 +0000 | |
---|---|---|
committer | 2022-07-15 16:27:42 +0000 | |
commit | 16a12aee22a313a7c902f36a18488375e30477da (patch) | |
tree | b2fd16beabfb88a19a0cb46ec03b41be932efd3d /libs/binder/RpcState.cpp | |
parent | f2532967f521b8c6e7083c88ccde04af2f045736 (diff) |
libbinder: Don't abort when rpc parcel size is invalid
No test becaue this is only reachable by bypassing the binder client
library (i.e. writing non-sense directly to the socket).
Test: binder_rpc_fuzzer
Bug: 238497894
Change-Id: I85ef57df4b8970c35904a5e84e61cb87653a39be
Diffstat (limited to 'libs/binder/RpcState.cpp')
-rw-r--r-- | libs/binder/RpcState.cpp | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/libs/binder/RpcState.cpp b/libs/binder/RpcState.cpp index 0ae75cdefa..a89849797c 100644 --- a/libs/binder/RpcState.cpp +++ b/libs/binder/RpcState.cpp @@ -643,14 +643,21 @@ status_t RpcState::waitForReply(const sp<RpcSession::RpcConnection>& connection, Span<const uint32_t> objectTableSpan; if (session->getProtocolVersion().value() >= RPC_WIRE_PROTOCOL_VERSION_RPC_HEADER_FEATURE_EXPLICIT_PARCEL_SIZE) { - Span<const uint8_t> objectTableBytes = parcelSpan.splitOff(rpcReply.parcelDataSize); + std::optional<Span<const uint8_t>> objectTableBytes = + parcelSpan.splitOff(rpcReply.parcelDataSize); + if (!objectTableBytes.has_value()) { + ALOGE("Parcel size larger than available bytes: %" PRId32 " vs %zu. Terminating!", + rpcReply.parcelDataSize, parcelSpan.byteSize()); + (void)session->shutdownAndWait(false); + return BAD_VALUE; + } std::optional<Span<const uint32_t>> maybeSpan = - objectTableBytes.reinterpret<const uint32_t>(); + objectTableBytes->reinterpret<const uint32_t>(); if (!maybeSpan.has_value()) { ALOGE("Bad object table size inferred from RpcWireReply. Saw bodySize=%" PRId32 " sizeofHeader=%zu parcelSize=%" PRId32 " objectTableBytesSize=%zu. Terminating!", command.bodySize, rpcReplyWireSize, rpcReply.parcelDataSize, - objectTableBytes.size); + objectTableBytes->size); return BAD_VALUE; } objectTableSpan = *maybeSpan; @@ -893,15 +900,22 @@ processTransactInternalTailCall: Span<const uint32_t> objectTableSpan; if (session->getProtocolVersion().value() > RPC_WIRE_PROTOCOL_VERSION_RPC_HEADER_FEATURE_EXPLICIT_PARCEL_SIZE) { - Span<const uint8_t> objectTableBytes = parcelSpan.splitOff(transaction->parcelDataSize); + std::optional<Span<const uint8_t>> objectTableBytes = + parcelSpan.splitOff(transaction->parcelDataSize); + if (!objectTableBytes.has_value()) { + ALOGE("Parcel size (%" PRId32 ") greater than available bytes (%zu). Terminating!", + transaction->parcelDataSize, parcelSpan.byteSize()); + (void)session->shutdownAndWait(false); + return BAD_VALUE; + } std::optional<Span<const uint32_t>> maybeSpan = - objectTableBytes.reinterpret<const uint32_t>(); + objectTableBytes->reinterpret<const uint32_t>(); if (!maybeSpan.has_value()) { ALOGE("Bad object table size inferred from RpcWireTransaction. Saw bodySize=%zu " "sizeofHeader=%zu parcelSize=%" PRId32 " objectTableBytesSize=%zu. Terminating!", transactionData.size(), sizeof(RpcWireTransaction), - transaction->parcelDataSize, objectTableBytes.size); + transaction->parcelDataSize, objectTableBytes->size); return BAD_VALUE; } objectTableSpan = *maybeSpan; |