• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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