• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3  * Licensed under the Mulan PSL v2.
4  * You can use this software according to the terms and conditions of the Mulan PSL v2.
5  * You may obtain a copy of Mulan PSL v2 at:
6  *     http://license.coscl.org.cn/MulanPSL2
7  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8  * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9  * PURPOSE.
10  * See the Mulan PSL v2 for more details.
11  */
12 
13 #include "cadaemon_stub.h"
14 #include <malloc.h>
15 #include <memory>
16 #include <securec.h>
17 #include "ipc_skeleton.h"
18 #include "ipc_types.h"
19 #include "string_ex.h"
20 #include "tee_client_api.h"
21 #include "tee_client_inner.h"
22 #include "tee_log.h"
23 
24 using namespace std;
25 
26 namespace OHOS {
27 namespace CaDaemon {
28 const std::u16string INTERFACE_TOKEN = u"ohos.tee_client.accessToken";
29 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)30 int32_t CaDaemonStub::OnRemoteRequest(uint32_t code,
31     MessageParcel& data, MessageParcel &reply, MessageOption &option)
32 {
33     tlogi("CaDaemonStub::OnReceived, code = %" PUBLIC "u, flags= %" PUBLIC "d.", code, option.GetFlags());
34     int32_t result;
35     (void)mallopt(M_SET_THREAD_CACHE, M_THREAD_CACHE_DISABLE);
36     (void)mallopt(M_DELAYED_FREE, M_DELAYED_FREE_DISABLE);
37     switch (code) {
38         case static_cast<uint32_t>(CadaemonOperationInterfaceCode::INIT_CONTEXT):
39             result = InitContextRecvProc(data, reply);
40             break;
41         case static_cast<uint32_t>(CadaemonOperationInterfaceCode::FINAL_CONTEXT):
42             result = FinalContextRecvProc(data, reply);
43             break;
44         case static_cast<uint32_t>(CadaemonOperationInterfaceCode::OPEN_SESSION):
45             result = OpenSessionRecvProc(data, reply);
46             break;
47         case static_cast<uint32_t>(CadaemonOperationInterfaceCode::CLOSE_SESSION):
48             result = CloseSessionRecvProc(data, reply);
49             break;
50         case static_cast<uint32_t>(CadaemonOperationInterfaceCode::INVOKE_COMMND):
51             result = InvokeCommandRecvProc(data, reply);
52             break;
53         case static_cast<uint32_t>(CadaemonOperationInterfaceCode::REGISTER_MEM):
54             result = RegisterMemRecvProc(data, reply);
55             break;
56         case static_cast<uint32_t>(CadaemonOperationInterfaceCode::ALLOC_MEM):
57             result = AllocMemRecvProc(data, reply);
58             break;
59         case static_cast<uint32_t>(CadaemonOperationInterfaceCode::RELEASE_MEM):
60             result = ReleaseMemRecvProc(data, reply);
61             break;
62         case static_cast<uint32_t>(CadaemonOperationInterfaceCode::SET_CALL_BACK):
63             result = SetCallBackRecvProc(data, reply);
64             break;
65         case static_cast<uint32_t>(CadaemonOperationInterfaceCode::SEND_SECFILE):
66             result = SendSecFileRecvProc(data, reply);
67             break;
68         case static_cast<uint32_t>(CadaemonOperationInterfaceCode::GET_TEE_VERSION):
69             result = GetTeeVersionRecvProc(data, reply);
70             break;
71         default:
72             tlogi("CaDaemonStub: default case, need check");
73             (void)mallopt(M_FLUSH_THREAD_CACHE, 0);
74             return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
75     }
76 
77     (void)mallopt(M_FLUSH_THREAD_CACHE, 0);
78     return result;
79 }
80 
GetChar(MessageParcel & data,char tempChar[],const char ** str)81 static bool GetChar(MessageParcel &data, char tempChar[], const char **str)
82 {
83     uint32_t strLen;
84     string tempStr;
85     int32_t ret;
86 
87     ret = data.ReadUint32(strLen);
88     CHECK_ERR_RETURN(ret, true, ret);
89 
90     if (strLen > 0) {
91         ret = data.ReadString(tempStr);
92         CHECK_ERR_RETURN(ret, true, ret);
93         if (strnlen(tempStr.c_str(), PATH_MAX) == PATH_MAX || strLen != strnlen(tempStr.c_str(), PATH_MAX)) {
94             tloge("recv str length check fail\n");
95             return false;
96         }
97 
98         if (strcpy_s(tempChar, PATH_MAX + 1, tempStr.c_str()) != EOK) {
99             tloge("copy str fail, errno = %" PUBLIC "d\n", errno);
100             return false;
101         }
102         *str = tempChar;
103     }
104 
105     return true;
106 }
107 
InitContextRecvProc(MessageParcel & data,MessageParcel & reply)108 int32_t CaDaemonStub::InitContextRecvProc(MessageParcel &data, MessageParcel &reply)
109 {
110     if (!EnforceInterceToken(data)) {
111         tloge("CaDaemonStub: InitContextRecvProc interface token check failed!");
112         return ERR_UNKNOWN_REASON;
113     }
114 
115     const char *name = nullptr;
116     char tempChar[PATH_MAX + 1] = { 0 };
117     if (!GetChar(data, tempChar, &name)) {
118         tloge("InitContextRecvProc: get name failed\n");
119         return ERR_UNKNOWN_OBJECT;
120     }
121 
122     if (InitializeContext(name, reply) != TEEC_SUCCESS) {
123         tloge("initialize context failed\n");
124         return ERR_UNKNOWN_REASON;
125     }
126 
127     return ERR_NONE;
128 }
129 
FinalContextRecvProc(MessageParcel & data,MessageParcel & reply)130 int32_t CaDaemonStub::FinalContextRecvProc(MessageParcel &data, MessageParcel &reply)
131 {
132     (void)reply;
133     if (!EnforceInterceToken(data)) {
134         tloge("CaDaemonStub: FinalContextRecvProc interface token check failed!");
135         return -1;
136     }
137 
138     TEEC_Context *context = nullptr;
139     size_t len = sizeof(*context);
140     context = (TEEC_Context *)(data.ReadBuffer(len));
141     if (context == nullptr) {
142         return ERR_UNKNOWN_OBJECT;
143     }
144 
145     if (FinalizeContext(context) != TEEC_SUCCESS) {
146         return ERR_UNKNOWN_REASON;
147     }
148 
149     return ERR_NONE;
150 }
151 
GetContextFromData(MessageParcel & data,TEEC_Context * context)152 static bool GetContextFromData(MessageParcel &data, TEEC_Context *context)
153 {
154     size_t len = sizeof(*context);
155     TEEC_Context *tempContext = (TEEC_Context *)(data.ReadBuffer(len));
156     if (tempContext == nullptr) {
157         return false;
158     }
159 
160     if (memcpy_s(context, len, tempContext, len) != EOK) {
161         tloge("getContext: operation memcpy failed\n");
162         return false;
163     }
164     return true;
165 }
166 
GetSessionFromData(MessageParcel & data,TEEC_Session * session)167 static bool GetSessionFromData(MessageParcel &data, TEEC_Session *session)
168 {
169     TEEC_Session *tempSession = nullptr;
170     size_t len = sizeof(*tempSession);
171     tempSession = (TEEC_Session *)(data.ReadBuffer(len));
172     if (tempSession == nullptr) {
173         return false;
174     }
175 
176     if (memcpy_s(session, len, tempSession, len) != EOK) {
177         tloge("getSession: operation memcpy failed\n");
178         return false;
179     }
180     return true;
181 }
182 
GetSharedMemFromData(MessageParcel & data,TEEC_SharedMemory * shm)183 static bool GetSharedMemFromData(MessageParcel &data, TEEC_SharedMemory *shm)
184 {
185     tlogi("start to recieve sharedmem\n");
186     TEEC_SharedMemory *tempShm = nullptr;
187     size_t len = sizeof(*tempShm);
188     tempShm = (TEEC_SharedMemory *)(data.ReadBuffer(len));
189     if (tempShm == nullptr) {
190         return false;
191     }
192 
193     if (memcpy_s(shm, len, tempShm, len) != EOK) {
194         tloge("getShamem: operation memcpy failed\n");
195         return false;
196     }
197     return true;
198 }
199 
SetInvalidIonFd(TEEC_Operation * operation)200 static void SetInvalidIonFd(TEEC_Operation *operation)
201 {
202     uint32_t paramType[TEEC_PARAM_NUM] = { 0 };
203     for (uint32_t paramCnt = 0; paramCnt < TEEC_PARAM_NUM; paramCnt++) {
204         paramType[paramCnt] = TEEC_PARAM_TYPE_GET(operation->paramTypes, paramCnt);
205         if (paramType[paramCnt] == TEEC_ION_INPUT) {
206             operation->params[paramCnt].ionref.ion_share_fd = -1;
207         }
208     }
209 }
210 
CloseDupIonFd(TEEC_Operation * operation)211 static void CloseDupIonFd(TEEC_Operation *operation)
212 {
213     uint32_t paramType[TEEC_PARAM_NUM] = { 0 };
214     for (uint32_t paramCnt = 0; paramCnt < TEEC_PARAM_NUM; paramCnt++) {
215         paramType[paramCnt] = TEEC_PARAM_TYPE_GET(operation->paramTypes, paramCnt);
216         if (paramType[paramCnt] != TEEC_ION_INPUT) {
217             continue;
218         }
219         if (operation->params[paramCnt].ionref.ion_share_fd >= 0) {
220             close(operation->params[paramCnt].ionref.ion_share_fd);
221         }
222     }
223 }
224 
GetOperationFromData(MessageParcel & data,TEEC_Operation * operation,bool & opFlag)225 static bool GetOperationFromData(MessageParcel &data, TEEC_Operation *operation, bool &opFlag)
226 {
227     bool retTmp = data.ReadBool(opFlag);
228     uint32_t paramType[TEEC_PARAM_NUM] = { 0 };
229     CHECK_ERR_RETURN(retTmp, true, retTmp);
230 
231     if (!opFlag) {
232         tloge("operation is nullptr\n");
233         return true;
234     }
235 
236     size_t len = sizeof(*operation);
237     TEEC_Operation *tempOp = (TEEC_Operation *)(data.ReadBuffer(len));
238     if (tempOp == nullptr) {
239         return false;
240     }
241 
242     if (memcpy_s(operation, len, tempOp, len) != EOK) {
243         tloge("getOperation: operation memcpy failed\n");
244         return false;
245     }
246 
247     /* First, set ion fd invalid, easy to judge if a dup fd can be closed */
248     SetInvalidIonFd(operation);
249     /* clear the pointer from ca to avoid access to invalid address */
250     operation->session = nullptr;
251     for (uint32_t paramCnt = 0; paramCnt < TEEC_PARAM_NUM; paramCnt++) {
252         paramType[paramCnt] = TEEC_PARAM_TYPE_GET(operation->paramTypes, paramCnt);
253         if (IS_TEMP_MEM(paramType[paramCnt])) {
254             operation->params[paramCnt].tmpref.buffer = nullptr;
255         } else if (IS_PARTIAL_MEM(paramType[paramCnt])) {
256             operation->params[paramCnt].memref.parent = nullptr;
257         } else if (paramType[paramCnt] == TEEC_ION_INPUT) {
258             operation->params[paramCnt].ionref.ion_share_fd = data.ReadFileDescriptor();
259             if (operation->params[paramCnt].ionref.ion_share_fd < 0) {
260                 tloge("read ion fd from parcel failed\n");
261                 CloseDupIonFd(operation);
262                 return false;
263             }
264         }
265     }
266     return true;
267 }
268 
269 
ReadFd(MessageParcel & data,int32_t & fd)270 static bool ReadFd(MessageParcel &data, int32_t &fd)
271 {
272     bool fdFlag = false;
273 
274     bool retTmp = data.ReadBool(fdFlag);
275     CHECK_ERR_RETURN(retTmp, true, retTmp);
276 
277     if (fdFlag) {
278         fd = data.ReadFileDescriptor();
279         if (fd < 0) {
280             tloge("read fd failed\n");
281             return false;
282         }
283         tloge("read fd success = %" PUBLIC "d\n", fd);
284     }
285     return true;
286 }
287 
ClearAsmMem(sptr<Ashmem> & optMem)288 static void ClearAsmMem(sptr<Ashmem> &optMem)
289 {
290     if (optMem != nullptr) {
291         optMem->UnmapAshmem();
292         optMem->CloseAshmem();
293     }
294 }
295 
GetOptMemFromData(MessageParcel & data,sptr<Ashmem> & optMem,uint32_t & optMemSize)296 static bool GetOptMemFromData(MessageParcel &data, sptr<Ashmem> &optMem, uint32_t &optMemSize)
297 {
298     bool retTmp = data.ReadUint32(optMemSize);
299     CHECK_ERR_RETURN(retTmp, true, retTmp);
300 
301     if (optMemSize > 0) {
302         optMem = data.ReadAshmem();
303         if (optMem == nullptr) {
304             tloge("get optMem failed\n");
305             return false;
306         }
307 
308         bool ret = optMem->MapReadAndWriteAshmem();
309         if (!ret) {
310             tloge("map ashmem failed\n");
311             return false;
312         }
313     }
314 
315     return true;
316 }
317 
ReadOpenData(MessageParcel & data,int32_t & fd,TEEC_UUID ** uuid,uint32_t & connMethod)318 static int32_t ReadOpenData(MessageParcel &data, int32_t &fd, TEEC_UUID **uuid, uint32_t &connMethod)
319 {
320     size_t len = sizeof(**uuid);
321 
322     bool retTmp = ReadFd(data, fd);
323     if (!retTmp) {
324         tloge("read ta fd failed\n");
325         goto ERROR;
326     }
327 
328     *uuid = (TEEC_UUID *)(data.ReadBuffer(len));
329     if (*uuid == nullptr) {
330         tloge("read uuid failed\n");
331         goto ERROR;
332     }
333 
334     retTmp = data.ReadUint32(connMethod);
335     if (!retTmp) {
336         tloge("read connection method failed\n");
337         goto ERROR;
338     }
339 
340     return ERR_NONE;
341 
342 ERROR:
343     if (fd >= 0) {
344         close(fd);
345     }
346 
347     return ERR_UNKNOWN_OBJECT;
348 }
349 
OpenSessionRecvProc(MessageParcel & data,MessageParcel & reply)350 int32_t CaDaemonStub::OpenSessionRecvProc(MessageParcel &data, MessageParcel &reply)
351 {
352     int32_t result = ERR_NONE;
353     if (!EnforceInterceToken(data)) {
354         tloge("CaDaemonStub: OpenSessionRecvProc interface token check failed!");
355         return -1;
356     }
357 
358     TEEC_Context context;
359     bool retTmp = GetContextFromData(data, &context);
360     CHECK_ERR_RETURN(retTmp, true, ERR_UNKNOWN_OBJECT);
361 
362     const char *taPath = nullptr;
363     char tempChar[PATH_MAX + 1] = { 0 };
364     retTmp = GetChar(data, tempChar, &taPath);
365     CHECK_ERR_RETURN(retTmp, true, ERR_UNKNOWN_OBJECT);
366     if (taPath != nullptr) {
367         tlogi("recieve taPath is not nullptr\n");
368         context.ta_path = reinterpret_cast<uint8_t *>(const_cast<char *>(taPath));
369     }
370 
371     uint32_t optMemSize;
372     sptr<Ashmem> optMem = nullptr;
373     int32_t fd = -1;
374     TEEC_UUID *uuid = nullptr;
375     uint32_t connMethod;
376     result = ReadOpenData(data, fd, &uuid, connMethod);
377     CHECK_ERR_RETURN(result, ERR_NONE, ERR_UNKNOWN_OBJECT);
378 
379     TEEC_Operation operation;
380     bool opFlag = false;
381     /* from now on, default return value is ERR_UNKNOWN_OBJECT */
382     result = ERR_UNKNOWN_OBJECT;
383     retTmp = GetOperationFromData(data, &operation, opFlag);
384     CHECK_ERR_GOTO(retTmp, true, END_CLEAR_FD);
385 
386     retTmp = GetOptMemFromData(data, optMem, optMemSize);
387     if (!retTmp) {
388         result = ERR_UNKNOWN_OBJECT;
389         goto END;
390     }
391 
392     if (opFlag) {
393         result = OpenSession(&context, taPath, fd, uuid, connMethod, &operation, optMemSize, optMem, reply);
394     } else {
395         result = OpenSession(&context, taPath, fd, uuid, connMethod, nullptr, optMemSize, optMem, reply);
396     }
397 
398 END:
399     ClearAsmMem(optMem);
400     CloseDupIonFd(&operation);
401 END_CLEAR_FD:
402     if (fd >= 0) {
403         close(fd);
404     }
405 
406     return result;
407 }
408 
CloseSessionRecvProc(MessageParcel & data,MessageParcel & reply)409 int32_t CaDaemonStub::CloseSessionRecvProc(MessageParcel &data, MessageParcel &reply)
410 {
411     (void)reply;
412     if (!EnforceInterceToken(data)) {
413         tloge("CaDaemonStub: CloseSessionRecvProc interface token check failed!");
414         return -1;
415     }
416 
417     TEEC_Context context;
418     bool retTmp = GetContextFromData(data, &context);
419     CHECK_ERR_RETURN(retTmp, true, ERR_UNKNOWN_OBJECT);
420 
421     TEEC_Session session;
422     retTmp = GetSessionFromData(data, &session);
423     CHECK_ERR_RETURN(retTmp, true, ERR_UNKNOWN_OBJECT);
424 
425     if (CloseSession(&session, &context) != TEEC_SUCCESS) {
426         return ERR_UNKNOWN_REASON;
427     }
428 
429     return ERR_NONE;
430 }
InvokeCommandRecvProc(MessageParcel & data,MessageParcel & reply)431 int32_t CaDaemonStub::InvokeCommandRecvProc(MessageParcel &data, MessageParcel &reply)
432 {
433     int32_t result = ERR_NONE;
434     if (!EnforceInterceToken(data)) {
435         tloge("CaDaemonStub: InvokeCommandRecvProc interface token check failed!");
436         return -1;
437     }
438 
439     TEEC_Context context;
440     bool retTmp = GetContextFromData(data, &context);
441     CHECK_ERR_RETURN(retTmp, true, ERR_UNKNOWN_OBJECT);
442 
443     TEEC_Session session;
444     retTmp = GetSessionFromData(data, &session);
445     CHECK_ERR_RETURN(retTmp, true, ERR_UNKNOWN_OBJECT);
446 
447     uint32_t commandID;
448     retTmp = data.ReadUint32(commandID);
449     CHECK_ERR_RETURN(retTmp, true, ERR_UNKNOWN_OBJECT);
450 
451     TEEC_Operation operation;
452     bool opFlag = false;
453     retTmp = GetOperationFromData(data, &operation, opFlag);
454     CHECK_ERR_RETURN(retTmp, true, ERR_UNKNOWN_OBJECT);
455 
456     uint32_t optMemSize;
457     sptr<Ashmem> optMem;
458     retTmp = GetOptMemFromData(data, optMem, optMemSize);
459     if (!retTmp) {
460         result = ERR_UNKNOWN_OBJECT;
461         goto END;
462     }
463 
464     if (opFlag) {
465         result = InvokeCommand(&context, &session, commandID, &operation, optMemSize, optMem, reply);
466     } else {
467         result = InvokeCommand(&context, &session, commandID, nullptr, optMemSize, optMem, reply);
468     }
469 
470 END:
471     ClearAsmMem(optMem);
472     CloseDupIonFd(&operation);
473     return result;
474 }
475 
RegisterMemRecvProc(MessageParcel & data,MessageParcel & reply)476 int32_t CaDaemonStub::RegisterMemRecvProc(MessageParcel &data, MessageParcel &reply)
477 {
478     if (!EnforceInterceToken(data)) {
479         tloge("CaDaemonStub: RegisterMemRecvProc interface token check failed!");
480         return -1;
481     }
482 
483     TEEC_Context context;
484     bool retTmp = GetContextFromData(data, &context);
485     CHECK_ERR_RETURN(retTmp, true, ERR_UNKNOWN_OBJECT);
486 
487     TEEC_SharedMemory sharedMem;
488     retTmp = GetSharedMemFromData(data, &sharedMem);
489     CHECK_ERR_RETURN(retTmp, true, ERR_UNKNOWN_OBJECT);
490 
491     if (RegisterSharedMemory(&context, &sharedMem, reply) != TEEC_SUCCESS) {
492         return ERR_UNKNOWN_REASON;
493     }
494 
495     return ERR_NONE;
496 }
497 
AllocMemRecvProc(MessageParcel & data,MessageParcel & reply)498 int32_t CaDaemonStub::AllocMemRecvProc(MessageParcel &data, MessageParcel &reply)
499 {
500     if (!EnforceInterceToken(data)) {
501         tloge("CaDaemonStub: AllocMemRecvProc interface token check failed!");
502         return -1;
503     }
504 
505     TEEC_Context context;
506     bool retTmp = GetContextFromData(data, &context);
507     CHECK_ERR_RETURN(retTmp, true, ERR_UNKNOWN_OBJECT);
508 
509     TEEC_SharedMemory sharedMem;
510     retTmp = GetSharedMemFromData(data, &sharedMem);
511     CHECK_ERR_RETURN(retTmp, true, ERR_UNKNOWN_OBJECT);
512 
513     if (AllocateSharedMemory(&context, &sharedMem, reply) != TEEC_SUCCESS) {
514         return ERR_UNKNOWN_REASON;
515     }
516 
517     return ERR_NONE;
518 }
519 
ReleaseMemRecvProc(MessageParcel & data,MessageParcel & reply)520 int32_t CaDaemonStub::ReleaseMemRecvProc(MessageParcel &data, MessageParcel &reply)
521 {
522     if (!EnforceInterceToken(data)) {
523         tloge("CaDaemonStub: ReleaseMemRecvProc interface token check failed!");
524         return -1;
525     }
526 
527     TEEC_Context context;
528     bool retTmp = GetContextFromData(data, &context);
529     CHECK_ERR_RETURN(retTmp, true, ERR_UNKNOWN_OBJECT);
530 
531     TEEC_SharedMemory sharedMem;
532     retTmp = GetSharedMemFromData(data, &sharedMem);
533     CHECK_ERR_RETURN(retTmp, true, ERR_UNKNOWN_OBJECT);
534 
535     uint32_t shmOffset;
536     retTmp = data.ReadUint32(shmOffset);
537     CHECK_ERR_RETURN(retTmp, true, ERR_UNKNOWN_OBJECT);
538 
539     ReleaseSharedMemory(&context, &sharedMem, shmOffset, reply);
540 
541     return ERR_NONE;
542 }
543 
SetCallBackRecvProc(MessageParcel & data,MessageParcel & reply)544 int32_t CaDaemonStub::SetCallBackRecvProc(MessageParcel &data, MessageParcel &reply)
545 {
546     if (!EnforceInterceToken(data)) {
547         tloge("CaDaemonStub: SetCallBackRecvProc interface token check failed!");
548         return -1;
549     }
550 
551     sptr<IRemoteObject> notify = nullptr;
552     notify = data.ReadRemoteObject();
553     if (notify == nullptr) {
554         tloge("CaDaemonStub: recieve notify is nullptr\n");
555         return ERR_NONE;
556     }
557 
558     return SetCallBack(notify);
559 }
560 
EnforceInterceToken(MessageParcel & data)561 bool CaDaemonStub::EnforceInterceToken(MessageParcel& data)
562 {
563     u16string interfaceToken = data.ReadInterfaceToken();
564     return interfaceToken == INTERFACE_TOKEN;
565 }
566 
SendSecFileRecvProc(MessageParcel & data,MessageParcel & reply)567 int32_t CaDaemonStub::SendSecFileRecvProc(MessageParcel& data, MessageParcel &reply)
568 {
569     if (!EnforceInterceToken(data)) {
570         tloge("CaDaemonStub: SendSecFileRecvProc interface token check failed!");
571         return -1;
572     }
573     const char *path = nullptr;
574     char tempChar[PATH_MAX + 1] = {0};
575     if (!GetChar(data, tempChar, &path)) {
576         tloge("SendSecFileRecvProc: get path failed\n");
577         return ERR_UNKNOWN_OBJECT;
578     }
579 
580     int fd = -1;
581     (void)ReadFd(data, fd);
582     if (fd < 0) {
583         tloge("SendSecFileRecvProc: ReadFd failed\n");
584         return ERR_UNKNOWN_OBJECT;
585     }
586 
587     TEEC_Context context;
588     if (GetContextFromData(data, &context) != true) {
589         tloge("SendSecFileRecvProc: get context failed\n");
590         close(fd);
591         return ERR_UNKNOWN_OBJECT;
592     }
593 
594     TEEC_Session session;
595     if (GetSessionFromData(data, &session) != true) {
596         tloge("SendSecFileRecvProc: get session failed\n");
597         close(fd);
598         return ERR_UNKNOWN_OBJECT;
599     }
600 
601     FILE *fp = fdopen(fd, "r");
602     if (fp != nullptr) {
603         (void)SendSecfile(path, context.fd, fp, reply);
604         /* within fclose function, fd has been closed */
605         fclose(fp);
606     } else {
607         tloge("SendSecFileRecvProc: fdopen failed\n");
608         close(fd);
609         return ERR_INVALID_DATA;
610     }
611 
612     return ERR_NONE;
613 }
614 
GetTeeVersionRecvProc(MessageParcel & data,MessageParcel & reply)615 int32_t CaDaemonStub::GetTeeVersionRecvProc(MessageParcel& data, MessageParcel &reply)
616 {
617     (void)GetTeeVersion(reply);
618     return ERR_NONE;
619 }
620 } // namespace CaDaemon
621 } // namespace OHOS
622