1 /*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef OHOS_IPC_DBINDER_BASE_INVOKER_H
17 #define OHOS_IPC_DBINDER_BASE_INVOKER_H
18
19 #include <unistd.h>
20 #include <cinttypes>
21 #include <memory>
22 #include <sys/types.h>
23 #include "securec.h"
24 #include "sys_binder.h"
25 #include "iremote_invoker.h"
26 #include "invoker_factory.h"
27
28 #include "ipc_object_stub.h"
29 #include "ipc_object_proxy.h"
30 #include "ipc_process_skeleton.h"
31 #include "ipc_thread_skeleton.h"
32 #include "ipc_debug.h"
33 #include "hitrace_invoker.h"
34 #include "dbinder_error_code.h"
35 #include "log_tags.h"
36
37 namespace OHOS {
38 using namespace OHOS::HiviewDFX;
39
40 static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_RPC, "DBinderBaseInvoker" };
41
42 template <class T> class DBinderBaseInvoker : public IRemoteInvoker {
43 public:
44 class DBinderSendAllocator : public DefaultAllocator {
45 void Dealloc(void *data) override;
46
47 friend DBinderBaseInvoker;
48 };
49
50 class DBinderRecvAllocator : public DefaultAllocator {
51 void Dealloc(void *data) override;
52
53 friend DBinderBaseInvoker;
54 };
55
56 virtual ~DBinderBaseInvoker() = default;
57 virtual std::shared_ptr<T> QueryServerSessionObject(uint32_t handle) = 0;
58 virtual bool UpdateClientSession(uint32_t handle, std::shared_ptr<T> sessionObject) = 0;
59
60 int SendRequest(int32_t handle, uint32_t code, MessageParcel &data, MessageParcel &reply,
61 MessageOption &option) override;
62 bool AddDeathRecipient(int32_t handle, void *cookie) override;
63 bool RemoveDeathRecipient(int32_t handle, void *cookie) override;
64 int GetObjectRefCount(const IRemoteObject *object) override;
65 bool SetMaxWorkThread(int maxThreadNum) override;
66 int SendReply(MessageParcel &reply, uint32_t flags, int32_t result) override;
67 bool PingService(int32_t handle) override;
68 sptr<IRemoteObject> GetSAMgrObject() override;
69 bool SetRegistryObject(sptr<IRemoteObject> &object) override;
70 void FreeBuffer(void *data) override;
71 virtual std::shared_ptr<T> WriteTransaction(int cmd, uint32_t flags, int32_t handle, int32_t socketId,
72 uint32_t code, MessageParcel &data, uint64_t &seqNumber, int status);
73 virtual int SendOrWaitForCompletion(int userWaitTime, uint64_t seqNumber, std::shared_ptr<T> sessionOfPeer,
74 MessageParcel *reply = nullptr);
75 virtual void OnTransaction(std::shared_ptr<ThreadProcessInfo> processInfo);
76 virtual void StartProcessLoop(uint32_t handle, const char *buffer, uint32_t size);
77 virtual uint32_t QueryHandleBySession(std::shared_ptr<T> session, uint64_t stubIndex) = 0;
78 virtual std::shared_ptr<T> QueryClientSessionObject(uint32_t databusHandle) = 0;
79 virtual std::shared_ptr<T> NewSessionOfBinderProxy(uint32_t handle, std::shared_ptr<T> session) = 0;
80 virtual std::shared_ptr<T> QuerySessionOfBinderProxy(uint32_t handle, std::shared_ptr<T> session) = 0;
81 virtual std::shared_ptr<T> CreateServerSessionObject(binder_uintptr_t binder, uint64_t &stubIndex,
82 std::shared_ptr<T> sessionObject) = 0;
83 virtual uint32_t FlattenSession(char *sessionOffset, const std::shared_ptr<T> connectSession,
84 uint64_t stubIndex) = 0;
85 virtual std::shared_ptr<T> UnFlattenSession(char *sessionOffset, uint64_t &stubIndex) = 0;
86 virtual int OnSendMessage(std::shared_ptr<T> sessionOfPeer) = 0;
87 virtual bool CreateProcessThread() = 0;
88 virtual uint64_t GetSeqNum() const = 0;
89 virtual void SetSeqNum(uint64_t seq) = 0;
90 virtual uint32_t GetClientFd() const = 0;
91 virtual void SetClientFd(uint32_t fd) = 0;
92 virtual void SetCallerPid(pid_t pid) = 0;
93 virtual void SetCallerUid(pid_t uid) = 0;
94 virtual void SetStatus(uint32_t status) = 0;
95 virtual void SetCallerDeviceID(const std::string &deviceId) = 0;
96 virtual void SetCallerTokenID(const uint32_t tokenId) = 0;
97 virtual int CheckAndSetCallerInfo(uint32_t listenFd, uint64_t stubIndex) = 0;
98 virtual int OnSendRawData(std::shared_ptr<T> session, const void *data, size_t size) = 0;
99 virtual bool SetTokenId(const dbinder_transaction_data *tr, std::shared_ptr<T> sessionObject) = 0;
100 bool CheckTransactionData(const dbinder_transaction_data *tr) const;
101
102 private:
103 uint32_t TranslateBinderType(flat_binder_object *binderObject, char *sessionOffset, std::shared_ptr<T> session);
104 uint32_t TranslateHandleType(flat_binder_object *binderObject, char *sessionOffset, std::shared_ptr<T> session);
105 bool TranslateRemoteHandleType(flat_binder_object *binderObject, char *sessionOffset, std::shared_ptr<T> session);
106 int HandleReply(uint64_t seqNumber, MessageParcel *reply, std::shared_ptr<T> sessionObject);
107 bool SetSenderStubIndex(std::shared_ptr<dbinder_transaction_data> transData, uint32_t handle);
108 int WaitForReply(uint64_t seqNumber, MessageParcel *reply, std::shared_ptr<T> sessionObject, int userWaitTime);
109 void ProcessTransaction(dbinder_transaction_data *tr, uint32_t listenFd);
110 void ProcessReply(dbinder_transaction_data *tr, uint32_t listenFd);
111 bool IRemoteObjectTranslate(char *dataBuffer, binder_size_t buffer_size, MessageParcel &data, uint32_t socketId,
112 std::shared_ptr<T> sessionObject);
113 bool TranslateRawData(char *dataBuffer, MessageParcel &data, uint32_t socketId);
114 std::shared_ptr<T> GetSessionObject(uint32_t handle, uint32_t socketId);
115 uint64_t GetUniqueSeqNumber(int cmd);
116 void ConstructTransData(dbinder_transaction_data &TransData, size_t totalSize, uint64_t seqNum, int cmd, __u32 code,
117 __u32 flags);
118 bool ProcessRawData(std::shared_ptr<T> sessionObject, MessageParcel &data, uint64_t seqNum);
119 std::shared_ptr<dbinder_transaction_data> ProcessNormalData(std::shared_ptr<T> sessionObject, MessageParcel &data,
120 int32_t handle, int32_t socketId, uint64_t seqNum, int cmd, __u32 code, __u32 flags, int status);
121 bool MoveTransData2Buffer(std::shared_ptr<T> sessionObject, std::shared_ptr<dbinder_transaction_data> transData);
122 bool MoveMessageParcel2TransData(MessageParcel &data, std::shared_ptr<T> sessionObject,
123 std::shared_ptr<dbinder_transaction_data> transData, int32_t socketId, int status);
124 std::shared_ptr<ThreadProcessInfo> MakeThreadProcessInfo(uint32_t handle, const char *buffer, uint32_t size);
125 std::shared_ptr<ThreadMessageInfo> MakeThreadMessageInfo(uint32_t handle);
126 uint32_t MakeRemoteHandle(std::shared_ptr<T> session, uint64_t stubIndex);
127 };
128
129 template <class T>
TranslateBinderType(flat_binder_object * binderObject,char * sessionOffset,std::shared_ptr<T> session)130 uint32_t DBinderBaseInvoker<T>::TranslateBinderType(flat_binder_object *binderObject, char *sessionOffset,
131 std::shared_ptr<T> session)
132 {
133 uint64_t stubIndex = 0;
134 std::shared_ptr<T> sessionOfPeer = CreateServerSessionObject(binderObject->binder, stubIndex, session);
135 if (sessionOfPeer == nullptr) {
136 ZLOGE(LOG_LABEL, "send an wrong stub object");
137 return 0;
138 }
139 binderObject->hdr.type = BINDER_TYPE_REMOTE_HANDLE;
140 binderObject->cookie = IRemoteObject::IF_PROT_DATABUS;
141 binderObject->binder = 0;
142 return FlattenSession(sessionOffset, sessionOfPeer, stubIndex);
143 }
144
145 template <class T>
TranslateHandleType(flat_binder_object * binderObject,char * sessionOffset,std::shared_ptr<T> session)146 uint32_t DBinderBaseInvoker<T>::TranslateHandleType(flat_binder_object *binderObject, char *sessionOffset,
147 std::shared_ptr<T> session)
148 {
149 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
150 if (current == nullptr) {
151 ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr");
152 return 0;
153 }
154 std::shared_ptr<T> sessionOfPeer = nullptr;
155 if (binderObject->cookie == IRemoteObject::IF_PROT_DATABUS) {
156 sessionOfPeer = QuerySessionOfBinderProxy(binderObject->handle, session);
157 } else if (binderObject->cookie == IRemoteObject::IF_PROT_BINDER) {
158 sessionOfPeer = NewSessionOfBinderProxy(binderObject->handle, session);
159 }
160 if (sessionOfPeer == nullptr) {
161 ZLOGE(LOG_LABEL, "send an wrong dbinder object");
162 return 0;
163 }
164
165 uint64_t stubIndex = current->QueryHandleToIndex(binderObject->handle);
166 if (stubIndex == 0) {
167 ZLOGE(LOG_LABEL, "stubIndex is zero");
168 return 0;
169 }
170 binderObject->hdr.type = BINDER_TYPE_REMOTE_HANDLE;
171
172 return FlattenSession(sessionOffset, sessionOfPeer, stubIndex);
173 }
174
MakeRemoteHandle(std::shared_ptr<T> session,uint64_t stubIndex)175 template <class T> uint32_t DBinderBaseInvoker<T>::MakeRemoteHandle(std::shared_ptr<T> session, uint64_t stubIndex)
176 {
177 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
178 if (current == nullptr) {
179 ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr");
180 return 0;
181 }
182
183 uint32_t handle = current->GetDBinderIdleHandle(stubIndex);
184 ZLOGI(LOG_LABEL, "create new handle = %{public}d", handle);
185 if (handle == 0) {
186 ZLOGE(LOG_LABEL, "add stub index err stubIndex = %" PRIu64 ",\
187 handle = %d", stubIndex, handle);
188 return 0;
189 }
190 if (!UpdateClientSession(handle, session)) {
191 ZLOGE(LOG_LABEL, "session create failed");
192 return 0;
193 }
194 return handle;
195 }
196
197 template <class T>
TranslateRemoteHandleType(flat_binder_object * binderObject,char * sessionOffset,std::shared_ptr<T> session)198 bool DBinderBaseInvoker<T>::TranslateRemoteHandleType(flat_binder_object *binderObject, char *sessionOffset,
199 std::shared_ptr<T> session)
200 {
201 std::shared_ptr<T> sessionOfPeer = nullptr;
202 uint64_t stubIndex = 0;
203
204 if (binderObject->cookie == IRemoteObject::IF_PROT_DATABUS ||
205 binderObject->cookie == IRemoteObject::IF_PROT_BINDER) {
206 sessionOfPeer = UnFlattenSession(sessionOffset, stubIndex);
207 }
208 if (sessionOfPeer == nullptr) {
209 ZLOGE(LOG_LABEL, "send a wrong dbinder object");
210 return false;
211 }
212 sessionOfPeer->SetFeatureSet(session->GetFeatureSet());
213
214 uint32_t handle = QueryHandleBySession(sessionOfPeer, stubIndex);
215 if (handle == 0) {
216 handle = MakeRemoteHandle(sessionOfPeer, stubIndex);
217 ZLOGI(LOG_LABEL, "create new handle = %{public}u", handle);
218 if (handle == 0) {
219 ZLOGE(LOG_LABEL, "failed to create new handle");
220 return false;
221 }
222 }
223 binderObject->hdr.type = BINDER_TYPE_HANDLE;
224 binderObject->handle = handle;
225 return true;
226 }
227
228 /* check data parcel contains object, if yes, get its session as payload of socket packet */
229 template <class T>
IRemoteObjectTranslate(char * dataBuffer,binder_size_t buffer_size,MessageParcel & data,uint32_t socketId,std::shared_ptr<T> sessionObject)230 bool DBinderBaseInvoker<T>::IRemoteObjectTranslate(char *dataBuffer, binder_size_t buffer_size, MessageParcel &data,
231 uint32_t socketId, std::shared_ptr<T> sessionObject)
232 {
233 if (data.GetOffsetsSize() <= 0 || dataBuffer == nullptr) {
234 return true;
235 }
236
237 uint32_t totalSize = 0;
238 binder_size_t *binderObjectsOffsets = reinterpret_cast<binder_size_t *>(data.GetObjectOffsets());
239 uint32_t offsetOfSession = buffer_size + data.GetOffsetsSize() * sizeof(binder_size_t);
240 char *flatOffset = dataBuffer + offsetOfSession;
241
242 for (size_t i = 0; i < data.GetOffsetsSize(); i++) {
243 auto binderObject = reinterpret_cast<flat_binder_object *>(dataBuffer + *(binderObjectsOffsets + i));
244 switch (binderObject->hdr.type) {
245 case BINDER_TYPE_BINDER: {
246 uint32_t flatSize = TranslateBinderType(binderObject, flatOffset + totalSize, sessionObject);
247 if (flatSize == 0) {
248 ZLOGE(LOG_LABEL, "send an wrong stub object");
249 return false;
250 }
251 totalSize += flatSize;
252 break;
253 }
254
255 case BINDER_TYPE_HANDLE: {
256 uint32_t flatSize = TranslateHandleType(binderObject, flatOffset + totalSize, sessionObject);
257 if (flatSize == 0) {
258 ZLOGE(LOG_LABEL, "send an wrong dbinder object");
259 return false;
260 }
261 totalSize += flatSize;
262 break;
263 }
264
265 case BINDER_TYPE_REMOTE_HANDLE: {
266 if (TranslateRemoteHandleType(binderObject, flatOffset + i * T::GetFlatSessionLen(),
267 sessionObject) != true) {
268 ZLOGE(LOG_LABEL, "send a wrong dbinder object");
269 return false;
270 }
271 break;
272 }
273
274 case BINDER_TYPE_FD: {
275 binderObject->hdr.type = BINDER_TYPE_FDR;
276 binderObject->handle = -1;
277 break;
278 }
279
280 case BINDER_TYPE_FDR: {
281 if (!TranslateRawData(dataBuffer, data, socketId)) {
282 ZLOGE(LOG_LABEL, "fail to translate big raw data");
283 // do nothing
284 }
285 break;
286 }
287 default: {
288 ZLOGE(LOG_LABEL, "do not support this type of translation");
289 // do nothing
290 break;
291 }
292 }
293 }
294
295 return true;
296 }
297
298 template <class T>
TranslateRawData(char * dataBuffer,MessageParcel & data,uint32_t socketId)299 bool DBinderBaseInvoker<T>::TranslateRawData(char *dataBuffer, MessageParcel &data, uint32_t socketId)
300 {
301 if (data.GetOffsetsSize() <= 0 || socketId == 0) {
302 ZLOGI(LOG_LABEL, "no raw data to translate.");
303 return true;
304 }
305
306 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
307 if (current == nullptr) {
308 ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr");
309 return false;
310 }
311 std::shared_ptr<InvokerRawData> receivedRawData = current->QueryRawData(socketId);
312 if (receivedRawData == nullptr) {
313 ZLOGE(LOG_LABEL, "cannot found rawData according to the socketId");
314 return false;
315 }
316 std::shared_ptr<char> rawData = receivedRawData->GetData();
317 size_t rawSize = receivedRawData->GetSize();
318 current->DetachRawData(socketId);
319 if (!data.RestoreRawData(rawData, rawSize)) {
320 ZLOGE(LOG_LABEL, "found rawData, but cannot restore them");
321 return false;
322 }
323 return true;
324 }
325
GetSessionObject(uint32_t handle,uint32_t socketId)326 template <class T> std::shared_ptr<T> DBinderBaseInvoker<T>::GetSessionObject(uint32_t handle, uint32_t socketId)
327 {
328 if (handle != 0) {
329 /* transact case */
330 return QueryServerSessionObject(handle);
331 } else {
332 /* reply case */
333 return QueryClientSessionObject(socketId);
334 }
335 }
336
GetUniqueSeqNumber(int cmd)337 template <class T> uint64_t DBinderBaseInvoker<T>::GetUniqueSeqNumber(int cmd)
338 {
339 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
340 if (current == nullptr) {
341 ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr");
342 return 0;
343 }
344
345 if (cmd == BC_TRANSACTION) {
346 return current->GetSeqNumber();
347 } else if (cmd == BC_REPLY) {
348 /* use sender sequence number */
349 return GetSeqNum();
350 } else {
351 return 0;
352 }
353 }
354
355 template <class T>
ConstructTransData(dbinder_transaction_data & TransData,size_t totalSize,uint64_t seqNum,int cmd,__u32 code,__u32 flags)356 void DBinderBaseInvoker<T>::ConstructTransData(dbinder_transaction_data &TransData, size_t totalSize, uint64_t seqNum,
357 int cmd, __u32 code, __u32 flags)
358 {
359 TransData.sizeOfSelf = totalSize;
360 TransData.magic = DBINDER_MAGICWORD;
361 TransData.version = VERSION_NUM;
362 TransData.cmd = cmd;
363 TransData.code = code;
364 TransData.flags = flags;
365 TransData.cookie = 0;
366 TransData.seqNumber = seqNum;
367 TransData.buffer_size = 0;
368 TransData.offsets_size = 0;
369 TransData.offsets = 0;
370 }
371
372 template <class T>
ProcessRawData(std::shared_ptr<T> sessionObject,MessageParcel & data,uint64_t seqNum)373 bool DBinderBaseInvoker<T>::ProcessRawData(std::shared_ptr<T> sessionObject, MessageParcel &data, uint64_t seqNum)
374 {
375 if (data.GetRawData() == nullptr || data.GetRawDataSize() == 0) {
376 return true; // do nothing, return true
377 }
378
379 std::shared_ptr<dbinder_transaction_data> transData = nullptr;
380 size_t totalSize = sizeof(dbinder_transaction_data) + data.GetRawDataSize();
381 transData.reset(reinterpret_cast<dbinder_transaction_data *>(::operator new(totalSize)));
382 if (transData == nullptr) {
383 ZLOGE(LOG_LABEL, "fail to create raw buffer with length = %{public}zu", totalSize);
384 return false;
385 }
386
387 ConstructTransData(*transData, totalSize, seqNum, BC_SEND_RAWDATA, 0, 0);
388 int result = memcpy_s(reinterpret_cast<char *>(transData.get()) + sizeof(dbinder_transaction_data),
389 totalSize - sizeof(dbinder_transaction_data), data.GetRawData(), data.GetRawDataSize());
390 if (result != 0) {
391 ZLOGE(LOG_LABEL, "memcpy data fail size = %{public}zu", data.GetRawDataSize());
392 return false;
393 }
394 result = OnSendRawData(sessionObject, transData.get(), totalSize);
395 if (result != 0) {
396 ZLOGE(LOG_LABEL, "fail to send raw data");
397 // do nothing, need send normal MessageParcel
398 }
399 return true;
400 }
401
402 template <class T>
MoveMessageParcel2TransData(MessageParcel & data,std::shared_ptr<T> sessionObject,std::shared_ptr<dbinder_transaction_data> transData,int32_t socketId,int status)403 bool DBinderBaseInvoker<T>::MoveMessageParcel2TransData(MessageParcel &data, std::shared_ptr<T> sessionObject,
404 std::shared_ptr<dbinder_transaction_data> transData, int32_t socketId, int status)
405 {
406 if (data.GetDataSize() > 0) {
407 /* Send this parcel's data through the socket. */
408 transData->buffer_size = data.GetDataSize();
409 uint32_t useSize = transData->sizeOfSelf - sizeof(dbinder_transaction_data);
410 int memcpyResult =
411 memcpy_s(transData->buffer, useSize, reinterpret_cast<void *>(data.GetData()), transData->buffer_size);
412 if (data.GetOffsetsSize() > 0) {
413 memcpyResult += memcpy_s(transData->buffer + transData->buffer_size, useSize - transData->buffer_size,
414 reinterpret_cast<void *>(data.GetObjectOffsets()), data.GetOffsetsSize() * sizeof(binder_size_t));
415 }
416 if (memcpyResult != 0) {
417 ZLOGE(LOG_LABEL, "parcel data memcpy_s failed");
418 return false;
419 }
420 transData->offsets_size = data.GetOffsetsSize() * sizeof(binder_size_t);
421 transData->offsets = transData->buffer_size;
422
423 if (!CheckTransactionData(transData.get())) {
424 ZLOGE(LOG_LABEL, "check trans data fail");
425 return false;
426 }
427 if (!IRemoteObjectTranslate(reinterpret_cast<char *>(transData->buffer), transData->buffer_size,
428 data, (uint32_t)socketId, sessionObject)) {
429 ZLOGE(LOG_LABEL, "translate object failed");
430 return false;
431 }
432 } else {
433 transData->flags |= TF_STATUS_CODE;
434 transData->buffer_size = sizeof(binder_size_t);
435 transData->offsets_size = static_cast<binder_size_t>(status);
436 transData->offsets = transData->buffer_size;
437 }
438 return true;
439 }
440
441 template <class T>
ProcessNormalData(std::shared_ptr<T> sessionObject,MessageParcel & data,int32_t handle,int32_t socketId,uint64_t seqNum,int cmd,__u32 code,__u32 flags,int status)442 std::shared_ptr<dbinder_transaction_data> DBinderBaseInvoker<T>::ProcessNormalData(std::shared_ptr<T> sessionObject,
443 MessageParcel &data, int32_t handle, int32_t socketId, uint64_t seqNum, int cmd, __u32 code, __u32 flags,
444 int status)
445 {
446 uint32_t sendSize = ((data.GetDataSize() > 0) ? data.GetDataSize() : sizeof(binder_size_t)) +
447 sizeof(struct dbinder_transaction_data) + data.GetOffsetsSize() * T::GetFlatSessionLen() +
448 data.GetOffsetsSize() * sizeof(binder_size_t);
449 std::shared_ptr<FeatureSetData> feature = sessionObject->GetFeatureSet();
450 if (feature == nullptr) {
451 ZLOGE(LOG_LABEL, "process normal data feature is null");
452 return nullptr;
453 }
454 if (IsATEnable(feature->featureSet) == true) {
455 sendSize += GetFeatureSize();
456 }
457
458 std::shared_ptr<dbinder_transaction_data> transData = nullptr;
459 transData.reset(reinterpret_cast<dbinder_transaction_data *>(::operator new(sendSize)));
460 if (transData == nullptr) {
461 ZLOGE(LOG_LABEL, "new buffer failed of length = %{public}u", sendSize);
462 return nullptr;
463 }
464 ConstructTransData(*transData, sendSize, seqNum, cmd, code, flags);
465
466 if (SetSenderStubIndex(transData, (uint32_t)handle) != true) {
467 ZLOGE(LOG_LABEL, "set stubIndex failed, handle = %{public}d", handle);
468 return nullptr;
469 }
470 if (MoveMessageParcel2TransData(data, sessionObject, transData, socketId, status) != true) {
471 ZLOGE(LOG_LABEL, "move parcel to transData failed, handle = %{public}d", handle);
472 return nullptr;
473 }
474 if (IsATEnable(feature->featureSet) == true) {
475 uint32_t bufferUseSize = transData->sizeOfSelf - sizeof(struct dbinder_transaction_data) - GetFeatureSize();
476 FeatureTransData *featureAddr = (FeatureTransData *)(transData->buffer + bufferUseSize);
477 if (SetFeatureTransData(featureAddr, GetFeatureSize()) == false) {
478 ZLOGE(LOG_LABEL, "set feature trans data failed");
479 return nullptr;
480 }
481 featureAddr->tokenId = feature->tokenId;
482 }
483 return transData;
484 }
485
486 template <class T>
MoveTransData2Buffer(std::shared_ptr<T> sessionObject,std::shared_ptr<dbinder_transaction_data> transData)487 bool DBinderBaseInvoker<T>::MoveTransData2Buffer(std::shared_ptr<T> sessionObject,
488 std::shared_ptr<dbinder_transaction_data> transData)
489 {
490 std::shared_ptr<BufferObject> sessionBuff = sessionObject->GetSessionBuff();
491 if (sessionBuff == nullptr) {
492 ZLOGE(LOG_LABEL, "get session buffer fail");
493 return false;
494 }
495
496 uint32_t sendSize = transData->sizeOfSelf;
497 char *sendBuffer = sessionBuff->GetSendBufferAndLock(sendSize);
498 /* session buffer contain mutex, need release mutex */
499 if (sendBuffer == nullptr) {
500 ZLOGE(LOG_LABEL, "buffer alloc failed in session");
501 return false;
502 }
503
504 sessionBuff->UpdateSendBuffer();
505 ssize_t writeCursor = sessionBuff->GetSendBufferWriteCursor();
506 ssize_t readCursor = sessionBuff->GetSendBufferReadCursor();
507 if (writeCursor < 0 || readCursor < 0 || sendSize > sessionBuff->GetSendBufferSize() - (uint32_t)writeCursor) {
508 sessionBuff->ReleaseSendBufferLock();
509 ZLOGE(LOG_LABEL, "sender's data is large than idle buffer");
510 return false;
511 }
512 if (memcpy_s(sendBuffer + writeCursor, sendSize, transData.get(), sendSize) != EOK) {
513 sessionBuff->ReleaseSendBufferLock();
514 ZLOGE(LOG_LABEL,
515 "fail to copy from tr to sendBuffer, parcelSize = %{public}u", sendSize);
516 return false;
517 }
518
519 writeCursor += static_cast<ssize_t>(sendSize);
520 sessionBuff->SetSendBufferWriteCursor(writeCursor);
521 sessionBuff->SetSendBufferReadCursor(readCursor);
522 sessionBuff->ReleaseSendBufferLock();
523 return true;
524 }
525
526 template <class T>
WriteTransaction(int cmd,uint32_t flags,int32_t handle,int32_t socketId,uint32_t code,MessageParcel & data,uint64_t & seqNumber,int status)527 std::shared_ptr<T> DBinderBaseInvoker<T>::WriteTransaction(int cmd, uint32_t flags, int32_t handle, int32_t socketId,
528 uint32_t code, MessageParcel &data, uint64_t &seqNumber, int status)
529 {
530 std::shared_ptr<T> sessionObject = GetSessionObject(handle, socketId);
531 if (sessionObject == nullptr) {
532 ZLOGE(LOG_LABEL,
533 "session is not exist for listenFd = %d, handle = %d", socketId, handle);
534 return nullptr;
535 }
536
537 uint64_t seqNum = GetUniqueSeqNumber(cmd);
538 if (seqNum == 0) {
539 ZLOGE(LOG_LABEL, "seqNum invalid");
540 return nullptr;
541 }
542 /* save seqNum for wait thread */
543 seqNumber = seqNum;
544 /* if MessageParcel has raw data, send raw data first, then send MessageParcel to peer */
545 if (ProcessRawData(sessionObject, data, seqNum) != true) {
546 ZLOGE(LOG_LABEL, "send rawdata failed");
547 return nullptr;
548 }
549 std::shared_ptr<dbinder_transaction_data> transData =
550 ProcessNormalData(sessionObject, data, handle, socketId, seqNum, cmd, code, flags, status);
551 if (transData == nullptr) {
552 ZLOGE(LOG_LABEL, "send normal data failed");
553 return nullptr;
554 }
555
556 if (MoveTransData2Buffer(sessionObject, transData) != true) {
557 ZLOGE(LOG_LABEL, "move transaction data to buffer failed");
558 return nullptr;
559 }
560 return sessionObject;
561 }
562
HandleReply(uint64_t seqNumber,MessageParcel * reply,std::shared_ptr<T> sessionObject)563 template <class T> int DBinderBaseInvoker<T>::HandleReply(uint64_t seqNumber, MessageParcel *reply,
564 std::shared_ptr<T> sessionObject)
565 {
566 if (reply == nullptr) {
567 ZLOGE(LOG_LABEL, "no need reply, free the buffer");
568 return RPC_BASE_INVOKER_INVALID_REPLY_ERR;
569 }
570
571 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
572 if (current == nullptr) {
573 ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr");
574 return RPC_BASE_INVOKER_INVALID_REPLY_ERR;
575 }
576 std::shared_ptr<ThreadMessageInfo> messageInfo = current->QueryThreadBySeqNumber(seqNumber);
577 if (messageInfo == nullptr) {
578 ZLOGE(LOG_LABEL, "receive buffer is nullptr");
579 #ifndef BUILD_PUBLIC_VERSION
580 ReportDriverEvent(DbinderErrorCode::COMMON_DRIVER_ERROR, DbinderErrorCode::ERROR_TYPE,
581 DbinderErrorCode::RPC_DRIVER, DbinderErrorCode::ERROR_CODE, DbinderErrorCode::HANDLE_RECV_DATA_FAILURE);
582 #endif
583 return RPC_BASE_INVOKER_INVALID_REPLY_ERR;
584 }
585
586 if (messageInfo->flags & MessageOption::TF_STATUS_CODE) {
587 int32_t err = static_cast<int32_t>(messageInfo->offsetsSize);
588 return err;
589 }
590 if (messageInfo->buffer == nullptr) {
591 ZLOGE(LOG_LABEL, "need reply message, but buffer is nullptr");
592 return RPC_BASE_INVOKER_INVALID_REPLY_ERR;
593 }
594 auto allocator = new (std::nothrow) DBinderRecvAllocator();
595 if (allocator == nullptr) {
596 ZLOGE(LOG_LABEL, "create DBinderRecvAllocator object failed");
597 return RPC_BASE_INVOKER_INVALID_REPLY_ERR;
598 }
599 if (!reply->SetAllocator(allocator)) {
600 ZLOGE(LOG_LABEL, "SetAllocator failed");
601 delete allocator;
602 return RPC_BASE_INVOKER_INVALID_REPLY_ERR;
603 }
604 reply->ParseFrom(reinterpret_cast<uintptr_t>(messageInfo->buffer), messageInfo->bufferSize);
605
606 if (messageInfo->offsetsSize > 0) {
607 reply->InjectOffsets(
608 reinterpret_cast<binder_uintptr_t>(reinterpret_cast<char *>(messageInfo->buffer) + messageInfo->offsets),
609 messageInfo->offsetsSize / sizeof(binder_size_t));
610 }
611
612 if (!IRemoteObjectTranslate(reinterpret_cast<char *>(messageInfo->buffer), messageInfo->bufferSize, *reply,
613 messageInfo->socketId, sessionObject)) {
614 ZLOGE(LOG_LABEL, "translate object failed");
615 return RPC_BASE_INVOKER_INVALID_REPLY_ERR;
616 }
617
618 return ERR_NONE;
619 }
620
621 template <class T>
SetSenderStubIndex(std::shared_ptr<dbinder_transaction_data> transData,uint32_t handle)622 bool DBinderBaseInvoker<T>::SetSenderStubIndex(std::shared_ptr<dbinder_transaction_data> transData, uint32_t handle)
623 {
624 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
625 if (current == nullptr) {
626 ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr");
627 return false;
628 }
629 transData->cookie = (handle == 0) ? 0 : current->QueryHandleToIndex(handle);
630 return true;
631 }
632
Dealloc(void * data)633 template <class T> void DBinderBaseInvoker<T>::DBinderSendAllocator::Dealloc(void *data) {}
634
Dealloc(void * data)635 template <class T> void DBinderBaseInvoker<T>::DBinderRecvAllocator::Dealloc(void *data)
636 {
637 delete[](unsigned char *) data;
638 }
639
640 template <class T>
WaitForReply(uint64_t seqNumber,MessageParcel * reply,std::shared_ptr<T> sessionObject,int userWaitTime)641 int DBinderBaseInvoker<T>::WaitForReply(uint64_t seqNumber, MessageParcel *reply,
642 std::shared_ptr<T> sessionObject, int userWaitTime)
643 {
644 /* if reply == nullptr, this is a one way message */
645 if (reply == nullptr) {
646 return NO_ERROR;
647 }
648
649 std::shared_ptr<ThreadMessageInfo> messageInfo = MakeThreadMessageInfo(sessionObject->GetSessionHandle());
650 if (messageInfo == nullptr) {
651 ZLOGE(LOG_LABEL, "make thread message info failed, no memory");
652 return RPC_BASE_INVOKER_WAIT_REPLY_ERR;
653 }
654
655 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
656 if (current == nullptr) {
657 ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr");
658 return RPC_BASE_INVOKER_WAIT_REPLY_ERR;
659 }
660 /* wait for reply */
661 if (!current->AddSendThreadInWait(seqNumber, messageInfo, userWaitTime)) {
662 ZLOGE(LOG_LABEL, "sender thread wait reply message time out");
663 return RPC_BASE_INVOKER_WAIT_REPLY_ERR;
664 }
665
666 int32_t err = HandleReply(seqNumber, reply, sessionObject);
667 current->EraseThreadBySeqNumber(seqNumber);
668 messageInfo->buffer = nullptr;
669 return err;
670 }
671
672 template <class T>
SendOrWaitForCompletion(int userWaitTime,uint64_t seqNumber,std::shared_ptr<T> sessionOfPeer,MessageParcel * reply)673 int DBinderBaseInvoker<T>::SendOrWaitForCompletion(int userWaitTime, uint64_t seqNumber,
674 std::shared_ptr<T> sessionOfPeer, MessageParcel *reply)
675 {
676 if (seqNumber == 0) {
677 ZLOGE(LOG_LABEL, "seqNumber can not be zero");
678 return RPC_BASE_INVOKER_INVALID_DATA_ERR;
679 }
680 if (sessionOfPeer == nullptr) {
681 ZLOGE(LOG_LABEL, "current session is invalid");
682 return RPC_BASE_INVOKER_INVALID_DATA_ERR;
683 }
684 int returnLen = OnSendMessage(sessionOfPeer);
685 if (returnLen != 0) {
686 ZLOGE(LOG_LABEL,
687 "fail to send to remote session with error = %{public}d", returnLen);
688 // no return, for msg send failed maybe not mine
689 }
690 return WaitForReply(seqNumber, reply, sessionOfPeer, userWaitTime);
691 }
692
693 template <class T>
SendRequest(int32_t handle,uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)694 int DBinderBaseInvoker<T>::SendRequest(int32_t handle, uint32_t code, MessageParcel &data, MessageParcel &reply,
695 MessageOption &option)
696 {
697 uint64_t seqNumber = 0;
698 int ret;
699
700 uint32_t flags = (uint32_t)option.GetFlags();
701 int userWaitTime = option.GetWaitTime();
702 MessageParcel &newData = const_cast<MessageParcel &>(data);
703 size_t oldWritePosition = newData.GetWritePosition();
704 HiTraceId traceId = HiTraceChain::GetId();
705 // set client send trace point if trace is enabled
706 HiTraceId childId = HitraceInvoker::TraceClientSend(handle, code, newData, flags, traceId);
707 std::shared_ptr<T> session = WriteTransaction(BC_TRANSACTION, flags, handle, 0, code, data, seqNumber, 0);
708 if (session == nullptr) {
709 newData.RewindWrite(oldWritePosition);
710 ZLOGE(LOG_LABEL, "seqNumber can not be zero,handle=%d", handle);
711 #ifndef BUILD_PUBLIC_VERSION
712 ReportDriverEvent(DbinderErrorCode::COMMON_DRIVER_ERROR, DbinderErrorCode::ERROR_TYPE,
713 DbinderErrorCode::RPC_DRIVER, DbinderErrorCode::ERROR_CODE, DbinderErrorCode::TRANSACT_DATA_FAILURE);
714 #endif
715 return RPC_BASE_INVOKER_WRITE_TRANS_ERR;
716 }
717
718 if (flags & TF_ONE_WAY) {
719 ret = SendOrWaitForCompletion(userWaitTime, seqNumber, session, nullptr);
720 } else {
721 ret = SendOrWaitForCompletion(userWaitTime, seqNumber, session, &reply);
722 }
723 HitraceInvoker::TraceClientReceieve(handle, code, flags, traceId, childId);
724 // restore Parcel data
725 newData.RewindWrite(oldWritePosition);
726 return ret;
727 }
728
AddDeathRecipient(int32_t handle,void * cookie)729 template <class T> bool DBinderBaseInvoker<T>::AddDeathRecipient(int32_t handle, void *cookie)
730 {
731 return true;
732 }
733
RemoveDeathRecipient(int32_t handle,void * cookie)734 template <class T> bool DBinderBaseInvoker<T>::RemoveDeathRecipient(int32_t handle, void *cookie)
735 {
736 return true;
737 }
738
GetObjectRefCount(const IRemoteObject * object)739 template <class T> int DBinderBaseInvoker<T>::GetObjectRefCount(const IRemoteObject *object)
740 {
741 return 0;
742 }
743
SetMaxWorkThread(int maxThreadNum)744 template <class T> bool DBinderBaseInvoker<T>::SetMaxWorkThread(int maxThreadNum)
745 {
746 return true;
747 }
748
SendReply(MessageParcel & reply,uint32_t flags,int32_t result)749 template <class T> int DBinderBaseInvoker<T>::SendReply(MessageParcel &reply, uint32_t flags, int32_t result)
750 {
751 uint64_t seqNumber = 0;
752 std::shared_ptr<T> sessionObject = WriteTransaction(BC_REPLY, flags, 0,
753 GetClientFd(), 0, reply, seqNumber, result);
754
755 if (seqNumber == 0) {
756 ZLOGE(LOG_LABEL, "seqNumber can not be zero");
757 return RPC_BASE_INVOKER_SEND_REPLY_ERR;
758 }
759 SendOrWaitForCompletion(0, seqNumber, sessionObject, nullptr);
760 return 0;
761 }
762
MakeThreadMessageInfo(uint32_t handle)763 template <class T> std::shared_ptr<ThreadMessageInfo> DBinderBaseInvoker<T>::MakeThreadMessageInfo(uint32_t handle)
764 {
765 std::shared_ptr<ThreadMessageInfo> messageInfo = std::make_shared<struct ThreadMessageInfo>();
766 if (messageInfo == nullptr) {
767 ZLOGE(LOG_LABEL, "no memory");
768 return nullptr;
769 }
770
771 messageInfo->threadId = std::this_thread::get_id();
772 messageInfo->buffer = nullptr;
773 messageInfo->offsets = 0;
774 messageInfo->socketId = handle;
775 return messageInfo;
776 }
777
778 template <class T>
MakeThreadProcessInfo(uint32_t handle,const char * inBuffer,uint32_t size)779 std::shared_ptr<ThreadProcessInfo> DBinderBaseInvoker<T>::MakeThreadProcessInfo(uint32_t handle, const char *inBuffer,
780 uint32_t size)
781 {
782 if (inBuffer == nullptr || size < sizeof(dbinder_transaction_data) || size > SOCKET_MAX_BUFF_SIZE) {
783 ZLOGE(LOG_LABEL, "buffer is null or size invalid");
784 return nullptr;
785 }
786
787 std::shared_ptr<ThreadProcessInfo> processInfo = std::make_shared<ThreadProcessInfo>();
788 if (processInfo == nullptr) {
789 ZLOGE(LOG_LABEL, "make_shared processInfo fail");
790 return nullptr;
791 }
792 std::shared_ptr<char> buffer(new (std::nothrow) char[size]);
793 if (buffer == nullptr) {
794 ZLOGE(LOG_LABEL, "new buffer failed of length = %{public}u", size);
795 return nullptr;
796 }
797
798 int memcpyResult = memcpy_s(buffer.get(), size, inBuffer, size);
799 if (memcpyResult != 0) {
800 ZLOGE(LOG_LABEL, "memcpy_s failed , size = %{public}u", size);
801 return nullptr;
802 }
803
804 processInfo->listenFd = handle;
805 processInfo->packageSize = size;
806 processInfo->buffer = buffer;
807 return processInfo;
808 }
809
StartProcessLoop(uint32_t handle,const char * buffer,uint32_t size)810 template <class T> void DBinderBaseInvoker<T>::StartProcessLoop(uint32_t handle, const char *buffer, uint32_t size)
811 {
812 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
813 if (current == nullptr) {
814 ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr");
815 return;
816 }
817 std::shared_ptr<ThreadProcessInfo> processInfo = MakeThreadProcessInfo(handle, buffer, size);
818 if (processInfo == nullptr) {
819 ZLOGE(LOG_LABEL, "processInfo is nullptr");
820 return;
821 }
822 std::thread::id threadId = current->GetIdleDataThread();
823 if (threadId == std::thread::id()) {
824 bool result = CreateProcessThread();
825 if (!result) {
826 int socketThreadNum = current->GetSocketTotalThreadNum();
827 ZLOGE(LOG_LABEL,
828 "create IO thread failed, current socket thread num=%d", socketThreadNum);
829 /* thread create too much, wait some thread be idle */
830 }
831 do {
832 /* no IO thread in idle state, wait a monent */
833 std::this_thread::sleep_for(std::chrono::milliseconds(1));
834 } while ((threadId = current->GetIdleDataThread()) == std::thread::id());
835 }
836
837 current->AddDataInfoToThread(threadId, processInfo);
838 current->WakeUpDataThread(threadId);
839 return;
840 }
841
ProcessTransaction(dbinder_transaction_data * tr,uint32_t listenFd)842 template <class T> void DBinderBaseInvoker<T>::ProcessTransaction(dbinder_transaction_data *tr, uint32_t listenFd)
843 {
844 int error;
845 MessageParcel data, reply;
846
847 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
848 if (current == nullptr) {
849 ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr");
850 return;
851 }
852
853 auto allocator = new (std::nothrow) DBinderSendAllocator();
854 if (allocator == nullptr) {
855 ZLOGE(LOG_LABEL, "DBinderSendAllocator Creation failed");
856 return;
857 }
858 if (!data.SetAllocator(allocator)) {
859 ZLOGE(LOG_LABEL, "SetAllocator failed");
860 delete allocator;
861 return;
862 }
863 data.ParseFrom(reinterpret_cast<uintptr_t>(tr->buffer), tr->buffer_size);
864 if (!(tr->flags & MessageOption::TF_STATUS_CODE) && tr->offsets_size > 0) {
865 data.InjectOffsets(reinterpret_cast<binder_uintptr_t>(reinterpret_cast<char *>(tr->buffer) + tr->offsets),
866 tr->offsets_size / sizeof(binder_size_t));
867 }
868 uint32_t &newflags = const_cast<uint32_t &>(tr->flags);
869 int isServerTraced = HitraceInvoker::TraceServerReceieve(tr->cookie, tr->code, data, newflags);
870
871 const pid_t oldPid = GetCallerPid();
872 const auto oldUid = static_cast<const uid_t>(GetCallerUid());
873 const std::string oldDeviceId = GetCallerDeviceID();
874 uint32_t oldStatus = GetStatus();
875 const uint32_t oldTokenId = GetCallerTokenID();
876 if (CheckAndSetCallerInfo(listenFd, tr->cookie) != ERR_NONE) {
877 ZLOGE(LOG_LABEL, "set user info error, maybe cookie is NOT belong to current caller");
878 return;
879 }
880 std::shared_ptr<T> sessionObject = QueryClientSessionObject(listenFd);
881 if (sessionObject == nullptr) {
882 ZLOGE(LOG_LABEL, "session is not exist for listenFd = %u", listenFd);
883 return;
884 }
885 if (SetTokenId(tr, sessionObject) != true) {
886 ZLOGE(LOG_LABEL, "set tokenid failed");
887 return;
888 }
889 SetStatus(IRemoteInvoker::ACTIVE_INVOKER);
890
891 const uint32_t flags = tr->flags;
892 uint64_t senderSeqNumber = tr->seqNumber;
893 if (tr->cookie == 0) {
894 // maybe cookie is zero, discard this package
895 return;
896 }
897
898 auto *stub = current->QueryStubByIndex(tr->cookie);
899 if (stub == nullptr) {
900 ZLOGE(LOG_LABEL, "stubIndex is invalid");
901 return;
902 }
903 if (!IRemoteObjectTranslate(reinterpret_cast<char *>(tr->buffer), tr->buffer_size, data,
904 listenFd, sessionObject)) {
905 ZLOGE(LOG_LABEL, "translate object failed");
906 return;
907 }
908
909 auto *stubObject = reinterpret_cast<IPCObjectStub *>(stub);
910 MessageOption option;
911 option.SetFlags(flags);
912 error = stubObject->SendRequest(tr->code, data, reply, option);
913 if (error != ERR_NONE) {
914 ZLOGE(LOG_LABEL, "stub is invalid, has not OnReceive or Request");
915 // can not return;
916 }
917 if (data.GetRawData() != nullptr) {
918 ZLOGE(LOG_LABEL, "delete raw data in process skeleton");
919 current->DetachRawData(listenFd);
920 }
921 HitraceInvoker::TraceServerSend(tr->cookie, tr->code, isServerTraced, newflags);
922 if (!(flags & MessageOption::TF_ASYNC)) {
923 SetClientFd(listenFd);
924 SetSeqNum(senderSeqNumber);
925 SendReply(reply, 0, error);
926 SetClientFd(0);
927 SetSeqNum(0);
928 }
929
930 SetCallerPid(oldPid);
931 SetCallerUid(oldUid);
932 SetCallerDeviceID(oldDeviceId);
933 SetStatus(oldStatus);
934 SetCallerTokenID(oldTokenId);
935 }
936
ProcessReply(dbinder_transaction_data * tr,uint32_t listenFd)937 template <class T> void DBinderBaseInvoker<T>::ProcessReply(dbinder_transaction_data *tr, uint32_t listenFd)
938 {
939 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
940 if (current == nullptr) {
941 ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr, can not wakeup thread");
942 return;
943 }
944
945 std::shared_ptr<ThreadMessageInfo> messageInfo = current->QueryThreadBySeqNumber(tr->seqNumber);
946 if (messageInfo == nullptr) {
947 ZLOGE(LOG_LABEL, "no thread waiting reply message of this seqNumber");
948 /* messageInfo is null, no thread need to wakeup */
949 return;
950 }
951
952 /* tr->sizeOfSelf > sizeof(dbinder_transaction_data) is checked in CheckTransactionData */
953 messageInfo->buffer = new (std::nothrow) unsigned char[tr->sizeOfSelf - sizeof(dbinder_transaction_data)];
954 if (messageInfo->buffer == nullptr) {
955 ZLOGE(LOG_LABEL, "some thread is waiting for reply message, but no memory");
956 /* wake up sender thread */
957 current->WakeUpThreadBySeqNumber(tr->seqNumber, listenFd);
958 return;
959 }
960 /* copy receive message to sender thread */
961 int memcpyResult = memcpy_s(messageInfo->buffer, tr->sizeOfSelf - sizeof(dbinder_transaction_data), tr->buffer,
962 tr->sizeOfSelf - sizeof(dbinder_transaction_data));
963 if (memcpyResult != 0) {
964 ZLOGE(LOG_LABEL, "memcpy_s failed");
965 delete[](unsigned char *) messageInfo->buffer;
966 messageInfo->buffer = nullptr;
967 /* wake up sender thread even no memssage */
968 current->WakeUpThreadBySeqNumber(tr->seqNumber, listenFd);
969 return;
970 }
971
972 messageInfo->flags = tr->flags;
973 messageInfo->bufferSize = tr->buffer_size;
974 messageInfo->offsetsSize = tr->offsets_size;
975 messageInfo->offsets = tr->offsets;
976 messageInfo->socketId = listenFd;
977
978 /* wake up sender thread */
979 current->WakeUpThreadBySeqNumber(tr->seqNumber, listenFd);
980 }
981
OnTransaction(std::shared_ptr<ThreadProcessInfo> processInfo)982 template <class T> void DBinderBaseInvoker<T>::OnTransaction(std::shared_ptr<ThreadProcessInfo> processInfo)
983 {
984 if (processInfo == nullptr) {
985 ZLOGE(LOG_LABEL, "processInfo is error!");
986 return;
987 }
988 uint32_t listenFd = processInfo->listenFd;
989 char *package = processInfo->buffer.get();
990
991 if (package == nullptr || listenFd == 0) {
992 ZLOGE(LOG_LABEL, "package is null or listenFd invalid!");
993 return;
994 }
995
996 dbinder_transaction_data *tr = reinterpret_cast<dbinder_transaction_data *>(package);
997 if (tr->sizeOfSelf < sizeof(dbinder_transaction_data)) {
998 ZLOGE(LOG_LABEL, "package is invalid");
999 return;
1000 }
1001
1002 if (tr->cmd == BC_TRANSACTION) {
1003 ProcessTransaction(tr, listenFd);
1004 } else if (tr->cmd == BC_REPLY) {
1005 ProcessReply(tr, listenFd);
1006 }
1007 return;
1008 }
1009
PingService(int32_t handle)1010 template <class T> bool DBinderBaseInvoker<T>::PingService(int32_t handle)
1011 {
1012 return true;
1013 }
1014
GetSAMgrObject()1015 template <class T> sptr<IRemoteObject> DBinderBaseInvoker<T>::GetSAMgrObject()
1016 {
1017 return nullptr;
1018 }
1019
1020
SetRegistryObject(sptr<IRemoteObject> & object)1021 template <class T> bool DBinderBaseInvoker<T>::SetRegistryObject(sptr<IRemoteObject> &object)
1022 {
1023 return true;
1024 }
1025
FreeBuffer(void * data)1026 template <class T> void DBinderBaseInvoker<T>::FreeBuffer(void *data)
1027 {
1028 return;
1029 }
1030
CheckTransactionData(const dbinder_transaction_data * tr)1031 template <class T> bool DBinderBaseInvoker<T>::CheckTransactionData(const dbinder_transaction_data *tr) const
1032 {
1033 if (tr->sizeOfSelf == 0 || tr->sizeOfSelf > SOCKET_MAX_BUFF_SIZE || tr->buffer_size > SOCKET_MAX_BUFF_SIZE ||
1034 tr->buffer_size == 0 || tr->offsets != tr->buffer_size ||
1035 tr->sizeOfSelf < sizeof(dbinder_transaction_data) + tr->buffer_size) {
1036 return false;
1037 }
1038 if ((tr->flags & MessageOption::TF_STATUS_CODE) && (tr->offsets != sizeof(binder_size_t))) {
1039 return false;
1040 }
1041 if (!(tr->flags & MessageOption::TF_STATUS_CODE)) {
1042 if (tr->offsets_size > (tr->sizeOfSelf - sizeof(dbinder_transaction_data) - tr->buffer_size)) {
1043 return false;
1044 }
1045 binder_size_t sessionSize =
1046 tr->sizeOfSelf - tr->buffer_size - sizeof(dbinder_transaction_data) - tr->offsets_size;
1047 if (sessionSize * sizeof(binder_size_t) < tr->offsets_size * T::GetFlatSessionLen()) {
1048 return false;
1049 }
1050 }
1051
1052 return true;
1053 }
1054 } // namespace OHOS
1055 #endif // OHOS_IPC_DBINDER_BASE_INVOKER_H
1056