summaryrefslogtreecommitdiff
path: root/libs/binder/RpcState.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/binder/RpcState.cpp')
-rw-r--r--libs/binder/RpcState.cpp29
1 files changed, 17 insertions, 12 deletions
diff --git a/libs/binder/RpcState.cpp b/libs/binder/RpcState.cpp
index 7ec8e0738d..f16a9ab98f 100644
--- a/libs/binder/RpcState.cpp
+++ b/libs/binder/RpcState.cpp
@@ -563,7 +563,7 @@ status_t RpcState::transactAddress(const sp<RpcSession::RpcConnection>& connecti
static void cleanup_reply_data(Parcel* p, const uint8_t* data, size_t dataSize,
const binder_size_t* objects, size_t objectsCount) {
(void)p;
- delete[] const_cast<uint8_t*>(data - offsetof(RpcWireReply, data));
+ delete[] const_cast<uint8_t*>(data);
(void)dataSize;
LOG_ALWAYS_FATAL_IF(objects != nullptr);
LOG_ALWAYS_FATAL_IF(objectsCount != 0, "%zu objects remaining", objectsCount);
@@ -585,25 +585,30 @@ status_t RpcState::waitForReply(const sp<RpcSession::RpcConnection>& connection,
return status;
}
- CommandData data(command.bodySize);
- if (!data.valid()) return NO_MEMORY;
-
- iovec iov{data.data(), command.bodySize};
- if (status_t status = rpcRec(connection, session, "reply body", &iov, 1); status != OK)
- return status;
-
if (command.bodySize < sizeof(RpcWireReply)) {
ALOGE("Expecting %zu but got %" PRId32 " bytes for RpcWireReply. Terminating!",
sizeof(RpcWireReply), command.bodySize);
(void)session->shutdownAndWait(false);
return BAD_VALUE;
}
- RpcWireReply* rpcReply = reinterpret_cast<RpcWireReply*>(data.data());
- if (rpcReply->status != OK) return rpcReply->status;
+ RpcWireReply rpcReply;
+ CommandData data(command.bodySize - sizeof(RpcWireReply));
+ if (!data.valid()) return NO_MEMORY;
+
+ iovec iovs[]{
+ {&rpcReply, sizeof(RpcWireReply)},
+ {data.data(), data.size()},
+ };
+ if (status_t status = rpcRec(connection, session, "reply body", iovs, arraysize(iovs));
+ status != OK)
+ return status;
+ if (rpcReply.status != OK) return rpcReply.status;
+
+ uint8_t* parcelData = data.data();
+ size_t parcelDataSize = data.size();
data.release();
- reply->rpcSetDataReference(session, rpcReply->data,
- command.bodySize - offsetof(RpcWireReply, data), cleanup_reply_data);
+ reply->rpcSetDataReference(session, parcelData, parcelDataSize, cleanup_reply_data);
return OK;
}