Skip to content

Commit 9d92bb8

Browse files
author
Orlando Arbildo
committed
libbinder: Handle large messages in Trusty
Added code to handle large binder messages in Trusty RPC Binder code. Bug: 368646945 Test: manual test app Change-Id: Ifc48a85b5119a7de2c872da06a6024f33214a342
1 parent 52b4e75 commit 9d92bb8

1 file changed

Lines changed: 66 additions & 28 deletions

File tree

libs/binder/trusty/RpcTransportTipcTrusty.cpp

Lines changed: 66 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,71 @@ class RpcTransportTipcTrusty : public RpcTransport {
4747
return mHaveMessage ? OK : WOULD_BLOCK;
4848
}
4949

50+
void moveMsgStart(ipc_msg_t* msg, size_t msg_size, size_t offset) {
51+
LOG_ALWAYS_FATAL_IF(offset > msg_size, "tried to move message past its end %zd>%zd", offset,
52+
msg_size);
53+
while (true) {
54+
if (offset == 0) {
55+
break;
56+
}
57+
if (offset >= msg->iov[0].iov_len) {
58+
// Move to the next iov, this one was sent already
59+
offset -= msg->iov[0].iov_len;
60+
msg->iov++;
61+
msg->num_iov -= 1;
62+
} else {
63+
// We need to move the base of the current iov
64+
msg->iov[0].iov_len -= offset;
65+
msg->iov[0].iov_base = static_cast<char*>(msg->iov[0].iov_base) + offset;
66+
offset = 0;
67+
}
68+
}
69+
// We only send handles on the first message. This can be changed in the future if we want
70+
// to send more handles than the maximum per message limit (which would require sending
71+
// multiple messages). The current code makes sure that we send less handles than the
72+
// maximum trusty allows.
73+
msg->num_handles = 0;
74+
}
75+
76+
status_t sendTrustyMsg(ipc_msg_t* msg, size_t msg_size) {
77+
do {
78+
ssize_t rc = send_msg(mSocket.fd.get(), msg);
79+
if (rc == ERR_NOT_ENOUGH_BUFFER) {
80+
// Peer is blocked, wait until it unblocks.
81+
// TODO: when tipc supports a send-unblocked handler,
82+
// save the message here in a queue and retry it asynchronously
83+
// when the handler gets called by the library
84+
uevent uevt;
85+
do {
86+
rc = ::wait(mSocket.fd.get(), &uevt, INFINITE_TIME);
87+
if (rc < 0) {
88+
return statusFromTrusty(rc);
89+
}
90+
if (uevt.event & IPC_HANDLE_POLL_HUP) {
91+
return DEAD_OBJECT;
92+
}
93+
} while (!(uevt.event & IPC_HANDLE_POLL_SEND_UNBLOCKED));
94+
95+
// Retry the send, it should go through this time because
96+
// sending is now unblocked
97+
rc = send_msg(mSocket.fd.get(), msg);
98+
}
99+
if (rc < 0) {
100+
return statusFromTrusty(rc);
101+
}
102+
size_t sent_bytes = static_cast<size_t>(rc);
103+
if (sent_bytes < msg_size) {
104+
moveMsgStart(msg, msg_size, static_cast<size_t>(sent_bytes));
105+
msg_size -= sent_bytes;
106+
} else {
107+
LOG_ALWAYS_FATAL_IF(static_cast<size_t>(rc) != msg_size,
108+
"Sent the wrong number of bytes %zd!=%zu", rc, msg_size);
109+
break;
110+
}
111+
} while (true);
112+
return OK;
113+
}
114+
50115
status_t interruptableWriteFully(
51116
FdTrigger* /*fdTrigger*/, iovec* iovs, int niovs,
52117
const std::optional<SmallFunction<status_t()>>& /*altPoll*/,
@@ -86,34 +151,7 @@ class RpcTransportTipcTrusty : public RpcTransport {
86151
msg.handles = msgHandles;
87152
}
88153

89-
ssize_t rc = send_msg(mSocket.fd.get(), &msg);
90-
if (rc == ERR_NOT_ENOUGH_BUFFER) {
91-
// Peer is blocked, wait until it unblocks.
92-
// TODO: when tipc supports a send-unblocked handler,
93-
// save the message here in a queue and retry it asynchronously
94-
// when the handler gets called by the library
95-
uevent uevt;
96-
do {
97-
rc = ::wait(mSocket.fd.get(), &uevt, INFINITE_TIME);
98-
if (rc < 0) {
99-
return statusFromTrusty(rc);
100-
}
101-
if (uevt.event & IPC_HANDLE_POLL_HUP) {
102-
return DEAD_OBJECT;
103-
}
104-
} while (!(uevt.event & IPC_HANDLE_POLL_SEND_UNBLOCKED));
105-
106-
// Retry the send, it should go through this time because
107-
// sending is now unblocked
108-
rc = send_msg(mSocket.fd.get(), &msg);
109-
}
110-
if (rc < 0) {
111-
return statusFromTrusty(rc);
112-
}
113-
LOG_ALWAYS_FATAL_IF(static_cast<size_t>(rc) != size,
114-
"Sent the wrong number of bytes %zd!=%zu", rc, size);
115-
116-
return OK;
154+
return sendTrustyMsg(&msg, size);
117155
}
118156

119157
status_t interruptableReadFully(

0 commit comments

Comments
 (0)