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 "teeclientopensession_fuzzer.h"
14
15 #include <cstddef>
16 #include <cstdint>
17 #include <securec.h>
18 #include "tee_client_api.h"
19 #include "message_parcel.h"
20 #include "tee_client_constants.h"
21 #include "tee_client_type.h"
22 #include "cadaemon_service.h"
23 #include "if_system_ability_manager.h"
24 #include "ipc_skeleton.h"
25 #include "ipc_types.h"
26 #include "iremote_proxy.h"
27 #include "iremote_stub.h"
28 #include "iservice_registry.h"
29 #include "system_ability_definition.h"
30 #include "tee_log.h"
31 #include "tee_client_ext_api.h"
32 #include "tee_client_inner.h"
33
34 static const TEEC_UUID g_testUuid = {
35 0x79b77788, 0x9789, 0x4a7a,
36 { 0xa2, 0xbe, 0xb6, 0x01, 0x55, 0xee, 0xf5, 0xf3 }
37 };
38
39 namespace OHOS {
RecOpenReply(uint32_t returnOrigin,TEEC_Result ret,TEEC_Session * outSession,TEEC_Operation * operation,MessageParcel & reply)40 static bool RecOpenReply(uint32_t returnOrigin, TEEC_Result ret, TEEC_Session *outSession,
41 TEEC_Operation *operation, MessageParcel &reply)
42 {
43 bool writeRet = reply.WriteUint32(returnOrigin);
44 CHECK_ERR_RETURN(writeRet, true, writeRet);
45
46 writeRet = reply.WriteInt32((int32_t)ret);
47 CHECK_ERR_RETURN(writeRet, true, writeRet);
48
49 if (ret != TEEC_SUCCESS) {
50 return false;
51 }
52
53 writeRet = reply.WriteBuffer(outSession, sizeof(*outSession));
54 CHECK_ERR_RETURN(writeRet, true, writeRet);
55
56 bool parRet = reply.WriteBool(true);
57 CHECK_ERR_RETURN(parRet, true, false);
58 writeRet = reply.WriteBuffer(operation, sizeof(*operation));
59 CHECK_ERR_RETURN(writeRet, true, writeRet);
60
61 return true;
62 }
63
TeeClientOpenSessionFuzzTest(const uint8_t * data,size_t size)64 bool TeeClientOpenSessionFuzzTest(const uint8_t *data, size_t size)
65 {
66 bool result = false;
67 if (size > sizeof(TEEC_Context) + sizeof(TEEC_Session) + sizeof(TEEC_UUID) + sizeof(uint32_t) +
68 sizeof(TEEC_Operation) + sizeof(uint32_t) + sizeof(TEEC_Parameter) + sizeof(TEEC_SharedMemory)) {
69 uint8_t *temp = const_cast<uint8_t *>(data);
70 TEEC_Context context = *reinterpret_cast<TEEC_Context *>(temp);
71 temp += sizeof(TEEC_Context);
72 TEEC_Session session = *reinterpret_cast<TEEC_Session *>(temp);
73 temp += sizeof(TEEC_Session);
74 TEEC_UUID uuid = *reinterpret_cast<TEEC_UUID *>(temp);
75 temp += sizeof(TEEC_UUID);
76 uint32_t connectionMethod = *reinterpret_cast<uint32_t *>(temp);
77 temp += sizeof(uint32_t);
78 TEEC_Operation operation = *reinterpret_cast<TEEC_Operation *>(temp);
79 temp += sizeof(TEEC_Operation);
80 uint32_t returnOrigin = *reinterpret_cast<uint32_t *>(temp);
81 temp += sizeof(uint32_t);
82
83 TEEC_Parameter param = *reinterpret_cast<TEEC_Parameter *>(temp);
84 temp += sizeof(TEEC_Parameter);
85 TEEC_SharedMemory memory = *reinterpret_cast<TEEC_SharedMemory *>(temp);
86 temp += sizeof(TEEC_SharedMemory);
87 char pathStr[MAX_TA_PATH_LEN + 1] = { 0 };
88 if (memcpy_s(pathStr, MAX_TA_PATH_LEN,
89 (const char*)data, size > MAX_TA_PATH_LEN ? MAX_TA_PATH_LEN : size) == 0) {
90 context.ta_path = (uint8_t *)pathStr;
91 }
92 memory.context = &context;
93 param.memref.parent = &memory;
94 operation.params[0] = param;
95 operation.params[1] = param;
96 operation.params[2] = param;
97 operation.params[3] = param;
98 operation.session = &session;
99
100 TEEC_Result ret = TEEC_OpenSession(&context, &session, &uuid, connectionMethod,
101 reinterpret_cast<const char *>(temp), &operation, &returnOrigin);
102 if (ret == TEEC_SUCCESS) {
103 TEEC_CloseSession(&session);
104 }
105
106 connectionMethod = TEEC_LOGIN_IDENTIFY;
107 ret = TEEC_OpenSession(&context, &session, &uuid, connectionMethod,
108 nullptr, &operation, &returnOrigin);
109 if (ret == TEEC_SUCCESS) {
110 TEEC_CloseSession(&session);
111 }
112 }
113 return result;
114 }
115
TeeClientOpenSessionFuzzTest_101(TEEC_Context * context,TEEC_Session * session,const TEEC_UUID * destination,uint32_t connectionMethod,const void * connectionData,TEEC_Operation * operation,uint32_t * returnOrigin)116 void TeeClientOpenSessionFuzzTest_101(TEEC_Context *context, TEEC_Session *session, const TEEC_UUID *destination,
117 uint32_t connectionMethod, const void *connectionData, TEEC_Operation *operation, uint32_t *returnOrigin)
118 {
119 operation->started = 1;
120 operation->paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE);
121
122 TEEC_Result ret = TEEC_OpenSession(context, session, destination, connectionMethod,
123 connectionData, operation, returnOrigin);
124 if (ret == TEEC_SUCCESS) {
125 TEEC_CloseSession(session);
126 }
127
128 operation->paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_OUTPUT, TEEC_MEMREF_PARTIAL_OUTPUT,
129 TEEC_MEMREF_PARTIAL_OUTPUT, TEEC_MEMREF_PARTIAL_OUTPUT);
130 ret = TEEC_OpenSession(context, session, destination, connectionMethod,
131 connectionData, operation, returnOrigin);
132 if (ret == TEEC_SUCCESS) {
133 TEEC_CloseSession(session);
134 }
135
136 operation->paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_OUTPUT, TEEC_MEMREF_PARTIAL_OUTPUT,
137 TEEC_NONE, TEEC_NONE);
138 ret = TEEC_OpenSession(context, session, destination, connectionMethod,
139 connectionData, operation, returnOrigin);
140 if (ret == TEEC_SUCCESS) {
141 TEEC_CloseSession(session);
142 }
143 }
144
TeeClientOpenSessionFuzzTest_1(const uint8_t * data,size_t size)145 bool TeeClientOpenSessionFuzzTest_1(const uint8_t *data, size_t size)
146 {
147 bool result = false;
148 if (size > sizeof(TEEC_Context) + sizeof(TEEC_Session) + sizeof(TEEC_UUID) + sizeof(uint32_t) +
149 sizeof(TEEC_Operation) + sizeof(uint32_t) + sizeof(TEEC_Parameter) + sizeof(TEEC_SharedMemory)) {
150 uint8_t *temp = const_cast<uint8_t *>(data);
151 TEEC_Context context = *reinterpret_cast<TEEC_Context *>(temp);
152 temp += sizeof(TEEC_Context);
153 TEEC_Session session = *reinterpret_cast<TEEC_Session *>(temp);
154 temp += sizeof(TEEC_Session);
155 TEEC_UUID uuid = *reinterpret_cast<TEEC_UUID *>(temp);
156 temp += sizeof(TEEC_UUID);
157 uint32_t connectionMethod = *reinterpret_cast<uint32_t *>(temp);
158 temp += sizeof(uint32_t);
159 TEEC_Operation operation = *reinterpret_cast<TEEC_Operation *>(temp);
160 temp += sizeof(TEEC_Operation);
161 uint32_t returnOrigin = *reinterpret_cast<uint32_t *>(temp);
162 temp += sizeof(uint32_t);
163
164 TEEC_Parameter param = *reinterpret_cast<TEEC_Parameter *>(temp);
165 temp += sizeof(TEEC_Parameter);
166 TEEC_SharedMemory memory = *reinterpret_cast<TEEC_SharedMemory *>(temp);
167 temp += sizeof(TEEC_SharedMemory);
168 char pathStr[MAX_TA_PATH_LEN + 1] = { 0 };
169 if (memcpy_s(pathStr, MAX_TA_PATH_LEN,
170 (const char*)data, size > MAX_TA_PATH_LEN ? MAX_TA_PATH_LEN : size) == 0) {
171 context.ta_path = (uint8_t *)pathStr;
172 }
173 memory.context = &context;
174 param.memref.parent = &memory;
175 operation.params[0] = param;
176 operation.params[1] = param;
177 operation.params[2] = param;
178 operation.params[3] = param;
179 operation.session = &session;
180
181 TEEC_Result ret = TEEC_OpenSession(&context, &session, &uuid, connectionMethod,
182 reinterpret_cast<const char *>(temp), &operation, &returnOrigin);
183 if (ret == TEEC_SUCCESS) {
184 TEEC_CloseSession(&session);
185 }
186
187 connectionMethod = TEEC_LOGIN_IDENTIFY;
188 ret = TEEC_OpenSession(&context, &session, &uuid, connectionMethod,
189 nullptr, &operation, &returnOrigin);
190 if (ret == TEEC_SUCCESS) {
191 TEEC_CloseSession(&session);
192 }
193
194 TeeClientOpenSessionFuzzTest_101(&context, &session, &uuid, connectionMethod,
195 nullptr, &operation, &returnOrigin);
196 }
197 return result;
198 }
199
TeeClientOpenSessionFuzzTest_2(const uint8_t * data,size_t size)200 void TeeClientOpenSessionFuzzTest_2(const uint8_t *data, size_t size)
201 {
202 TEEC_Context context = { 0 };
203 TEEC_Session session = { 0 };
204 TEEC_Operation operation = { 0 };
205 TEEC_SharedMemory sharedMem = { 0 };
206 char buff[128] = { 0 };
207 MessageParcel reply;
208 operation.started = 1;
209 uint32_t origin;
210 (void)TEEC_GetTEEVersion();
211 RecOpenReply(TEEC_ORIGIN_API, TEEC_SUCCESS, &session, &operation, reply);
212 TEEC_Result ret = TEEC_InitializeContext("CaDaemonTest_003", &context);
213
214 char pathStr[MAX_TA_PATH_LEN + 1] = { 0 };
215 if (memcpy_s(pathStr, MAX_TA_PATH_LEN,
216 (const char*)data, size > MAX_TA_PATH_LEN ? MAX_TA_PATH_LEN : size) == 0) {
217 context.ta_path = (uint8_t *)pathStr;
218 }
219
220 operation.paramTypes =
221 TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_OUTPUT, TEEC_MEMREF_PARTIAL_INPUT, TEEC_NONE, TEEC_NONE);
222 operation.params[0].memref.parent = &sharedMem;
223 operation.params[0].memref.parent->buffer = (void*)buff;
224 operation.params[0].memref.parent->flags = TEEC_MEM_OUTPUT;
225 operation.params[0].memref.parent->size = 0;
226 operation.params[0].memref.offset = 1;
227 operation.params[0].memref.size = 1;
228 operation.params[1].memref.parent = &sharedMem;
229 operation.params[1].memref.parent->buffer = (void*)buff;
230 operation.params[1].memref.parent->flags = TEEC_MEM_INPUT;
231 operation.params[1].memref.parent->size = -1;
232 operation.params[1].memref.offset = -1;
233 operation.params[1].memref.size = 1;
234 ret = TEEC_OpenSession(&context, &session, &g_testUuid, TEEC_LOGIN_IDENTIFY, nullptr, &operation, &origin);
235
236 operation.paramTypes =
237 TEEC_PARAM_TYPES(data[0], TEEC_NONE, TEEC_NONE, TEEC_NONE);
238 ret = TEEC_OpenSession(&context, &session, &g_testUuid, TEEC_LOGIN_IDENTIFY, nullptr, &operation, &origin);
239
240 ret = TEEC_SendSecfile(pathStr, &session);
241
242 TEEC_FinalizeContext(&context);
243 TEEC_CloseSession(&session);
244 TEEC_RequestCancellation(&operation);
245 }
246 }
247
248 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)249 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
250 {
251 /* Run your code on data */
252 OHOS::TeeClientOpenSessionFuzzTest(data, size);
253 OHOS::TeeClientOpenSessionFuzzTest_1(data, size);
254 OHOS::TeeClientOpenSessionFuzzTest_2(data, size);
255 return 0;
256 }