1 /*
2 * Copyright (c) 2024 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 #include "appspawn_client.h"
17 #include "appspawn_mount_permission.h"
18 #include "appspawn_hook.h"
19 #include "appspawn_utils.h"
20 #include "parameter.h"
21 #include "securec.h"
22
CalcFlagsUnits(uint32_t maxIndex)23 static inline int CalcFlagsUnits(uint32_t maxIndex)
24 {
25 return ((maxIndex / 32) + ((maxIndex % 32 == 0) ? 0 : 1)); // 32 max bit in uint32_t
26 }
27
SetAppSpawnMsgFlags(AppSpawnMsgFlags * msgFlags,uint32_t index)28 static inline int SetAppSpawnMsgFlags(AppSpawnMsgFlags *msgFlags, uint32_t index)
29 {
30 uint32_t blockIndex = index / 32; // 32 max bit in int
31 uint32_t bitIndex = index % 32; // 32 max bit in int
32 if (blockIndex < msgFlags->count) {
33 msgFlags->flags[blockIndex] |= (1 << bitIndex);
34 }
35 return 0;
36 }
37
CheckMsg(const AppSpawnReqMsgNode * reqNode,const AppSpawnTlv * tlv,const char * name)38 static inline int CheckMsg(const AppSpawnReqMsgNode *reqNode, const AppSpawnTlv *tlv, const char *name)
39 {
40 if ((reqNode->msg->msgLen + tlv->tlvLen) > MAX_MSG_TOTAL_LENGTH) {
41 APPSPAWN_LOGE("The message is too long %{public}s", name);
42 return APPSPAWN_MSG_INVALID;
43 }
44 if (reqNode->msg->msgType == MSG_GET_RENDER_TERMINATION_STATUS) {
45 if (tlv->tlvType != TLV_RENDER_TERMINATION_INFO) {
46 APPSPAWN_LOGE("Not support tlv %{public}s for message MSG_GET_RENDER_TERMINATION_STATUS", name);
47 return APPSPAWN_TLV_NOT_SUPPORT;
48 }
49 }
50 return 0;
51 }
52
CheckInputString(const char * info,const char * value,uint32_t maxLen)53 static inline int CheckInputString(const char *info, const char *value, uint32_t maxLen)
54 {
55 APPSPAWN_CHECK(value != NULL, return APPSPAWN_ARG_INVALID, "Invalid input info for %{public}s ", info);
56 uint32_t valueLen = (uint32_t)strlen(value);
57 APPSPAWN_CHECK(valueLen > 0 && valueLen < maxLen, return APPSPAWN_ARG_INVALID,
58 "Invalid input string length '%{public}s' for '%{public}s'", value, info);
59 return 0;
60 }
61
CreateAppSpawnMsgBlock(AppSpawnReqMsgNode * reqNode)62 static AppSpawnMsgBlock *CreateAppSpawnMsgBlock(AppSpawnReqMsgNode *reqNode)
63 {
64 AppSpawnMsgBlock *block = (AppSpawnMsgBlock *)calloc(1, MAX_MSG_BLOCK_LEN);
65 APPSPAWN_CHECK(block != NULL, return NULL, "Failed to create block");
66 OH_ListInit(&block->node);
67 block->blockSize = MAX_MSG_BLOCK_LEN - sizeof(AppSpawnMsgBlock);
68 block->currentIndex = 0;
69 OH_ListAddTail(&reqNode->msgBlocks, &block->node);
70 return block;
71 }
72
GetValidMsgBlock(const AppSpawnReqMsgNode * reqNode,uint32_t realLen)73 static AppSpawnMsgBlock *GetValidMsgBlock(const AppSpawnReqMsgNode *reqNode, uint32_t realLen)
74 {
75 AppSpawnMsgBlock *block = NULL;
76 struct ListNode *node = reqNode->msgBlocks.next;
77 while (node != &reqNode->msgBlocks) {
78 block = ListEntry(node, AppSpawnMsgBlock, node);
79 if ((block->blockSize - block->currentIndex) >= realLen) {
80 return block;
81 }
82 node = node->next;
83 }
84 return NULL;
85 }
86
GetTailMsgBlock(const AppSpawnReqMsgNode * reqNode)87 static AppSpawnMsgBlock *GetTailMsgBlock(const AppSpawnReqMsgNode *reqNode)
88 {
89 AppSpawnMsgBlock *block = NULL;
90 struct ListNode *node = reqNode->msgBlocks.prev;
91 if (node != &reqNode->msgBlocks) {
92 block = ListEntry(node, AppSpawnMsgBlock, node);
93 }
94 return block;
95 }
96
FreeMsgBlock(ListNode * node)97 static void FreeMsgBlock(ListNode *node)
98 {
99 AppSpawnMsgBlock *block = ListEntry(node, AppSpawnMsgBlock, node);
100 OH_ListRemove(node);
101 OH_ListInit(node);
102 free(block);
103 }
104
AddAppDataToBlock(AppSpawnMsgBlock * block,const uint8_t * data,uint32_t dataLen,int32_t dataType)105 static int AddAppDataToBlock(AppSpawnMsgBlock *block, const uint8_t *data, uint32_t dataLen, int32_t dataType)
106 {
107 APPSPAWN_CHECK(block->blockSize > block->currentIndex,
108 return APPSPAWN_BUFFER_NOT_ENOUGH, "Not enough buffer for data");
109 uint32_t reminderLen = block->blockSize - block->currentIndex;
110 uint32_t realDataLen = (dataType == DATA_TYPE_STRING) ? APPSPAWN_ALIGN(dataLen + 1) : APPSPAWN_ALIGN(dataLen);
111 APPSPAWN_CHECK(reminderLen >= realDataLen, return APPSPAWN_BUFFER_NOT_ENOUGH, "Not enough buffer for data");
112 int ret = memcpy_s(block->buffer + block->currentIndex, reminderLen, data, dataLen);
113 APPSPAWN_CHECK(ret == EOK, return APPSPAWN_SYSTEM_ERROR, "Failed to copy data");
114 if (dataType == DATA_TYPE_STRING) {
115 *((char *)block->buffer + block->currentIndex + dataLen) = '\0';
116 }
117 block->currentIndex += realDataLen;
118 return 0;
119 }
120
AddAppDataToTail(AppSpawnReqMsgNode * reqNode,const uint8_t * data,uint32_t dataLen,int32_t dataType)121 static int AddAppDataToTail(AppSpawnReqMsgNode *reqNode, const uint8_t *data, uint32_t dataLen, int32_t dataType)
122 {
123 uint32_t currLen = 0;
124 AppSpawnMsgBlock *block = GetTailMsgBlock(reqNode);
125 APPSPAWN_CHECK(block != NULL, return APPSPAWN_BUFFER_NOT_ENOUGH, "Not block info reqNode");
126 uint32_t realDataLen = (dataType == DATA_TYPE_STRING) ? dataLen + 1 : dataLen;
127 do {
128 uint32_t reminderBufferLen = block->blockSize - block->currentIndex;
129 uint32_t reminderDataLen = realDataLen - currLen;
130 uint32_t realLen = APPSPAWN_ALIGN(reminderDataLen);
131 uint32_t realCopy = 0;
132 if (reminderBufferLen >= realLen) { // 足够存储,直接保存
133 int ret = memcpy_s(block->buffer + block->currentIndex, reminderBufferLen, data + currLen, reminderDataLen);
134 APPSPAWN_CHECK(ret == EOK, return APPSPAWN_SYSTEM_ERROR, "Failed to copy data");
135 block->currentIndex += realLen;
136 break;
137 } else if (reminderBufferLen > 0) {
138 realCopy = reminderDataLen > reminderBufferLen ? reminderBufferLen : reminderDataLen;
139 int ret = memcpy_s(block->buffer + block->currentIndex, reminderBufferLen, data + currLen, realCopy);
140 APPSPAWN_CHECK(ret == EOK, return APPSPAWN_SYSTEM_ERROR, "Failed to copy data");
141 block->currentIndex += realCopy;
142 currLen += realCopy;
143 }
144 block = CreateAppSpawnMsgBlock(reqNode);
145 APPSPAWN_CHECK(block != NULL, return APPSPAWN_SYSTEM_ERROR, "Not enough buffer for data");
146 } while (currLen < realDataLen);
147 return 0;
148 }
149
AddAppDataEx(AppSpawnReqMsgNode * reqNode,const char * name,const AppSpawnAppData * data)150 static int AddAppDataEx(AppSpawnReqMsgNode *reqNode, const char *name, const AppSpawnAppData *data)
151 {
152 AppSpawnTlvExt tlv = {};
153 if (data->dataType == DATA_TYPE_STRING) {
154 tlv.tlvLen = APPSPAWN_ALIGN(data->dataLen + 1) + sizeof(AppSpawnTlvExt);
155 } else {
156 tlv.tlvLen = APPSPAWN_ALIGN(data->dataLen) + sizeof(AppSpawnTlvExt);
157 }
158 tlv.tlvType = TLV_MAX;
159 tlv.dataLen = data->dataLen;
160 tlv.dataType = data->dataType;
161 int ret = strcpy_s(tlv.tlvName, sizeof(tlv.tlvName), name);
162 APPSPAWN_CHECK(ret == 0, return APPSPAWN_SYSTEM_ERROR, "Failed to add data for %{public}s", name);
163 ret = CheckMsg(reqNode, (AppSpawnTlv *)&tlv, name);
164 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
165
166 APPSPAWN_LOGV("AddAppDataEx tlv [%{public}s %{public}u ] dataLen: %{public}u start: %{public}u",
167 name, tlv.tlvLen, data->dataLen, reqNode->msg->msgLen);
168 // 获取一个能保存改完整tlv的block
169 AppSpawnMsgBlock *block = GetValidMsgBlock(reqNode, tlv.tlvLen);
170 if (block != NULL) {
171 ret = AddAppDataToBlock(block, (uint8_t *)&tlv, sizeof(tlv), 0);
172 APPSPAWN_CHECK(ret == 0, return ret, "Failed to add tlv for %{public}s", name);
173 ret = AddAppDataToBlock(block, data->data, data->dataLen, data->dataType);
174 APPSPAWN_CHECK(ret == 0, return ret, "Failed to add data for %{public}s", name);
175 } else {
176 // 没有一个可用的block,最队列最后添加数据
177 ret = AddAppDataToTail(reqNode, (uint8_t *)&tlv, sizeof(tlv), 0);
178 APPSPAWN_CHECK(ret == 0, return ret, "Failed to add tlv to tail for %{public}s", name);
179 ret = AddAppDataToTail(reqNode, data->data, data->dataLen, data->dataType);
180 APPSPAWN_CHECK(ret == 0, return ret, "Failed to add data to tail for %{public}s", name);
181 }
182 reqNode->msg->tlvCount++;
183 reqNode->msg->msgLen += tlv.tlvLen;
184 APPSPAWN_LOGV("AddAppDataEx success name '%{public}s' end: %{public}u", name, reqNode->msg->msgLen);
185 return 0;
186 }
187
AddAppData(AppSpawnReqMsgNode * reqNode,uint32_t tlvType,const AppSpawnAppData * data,uint32_t count,const char * name)188 static int AddAppData(AppSpawnReqMsgNode *reqNode,
189 uint32_t tlvType, const AppSpawnAppData *data, uint32_t count, const char *name)
190 {
191 // 计算实际数据的长度
192 uint32_t realLen = sizeof(AppSpawnTlv);
193 uint32_t dataLen = 0;
194 for (uint32_t index = 0; index < count; index++) {
195 dataLen += data[index].dataLen;
196 realLen += (data[index].dataType == DATA_TYPE_STRING) ?
197 APPSPAWN_ALIGN(data[index].dataLen + 1) : APPSPAWN_ALIGN(data[index].dataLen);
198 }
199 AppSpawnTlv tlv;
200 tlv.tlvLen = realLen;
201 tlv.tlvType = tlvType;
202 int ret = CheckMsg(reqNode, &tlv, name);
203 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
204
205 APPSPAWN_LOGV("AddAppData tlv [%{public}s %{public}u] dataLen: %{public}u start: %{public}u",
206 name, tlv.tlvLen, dataLen, reqNode->msg->msgLen);
207 // 获取一个能保存改完整tlv的block
208 AppSpawnMsgBlock *block = GetValidMsgBlock(reqNode, tlv.tlvLen);
209 if (block != NULL) {
210 ret = AddAppDataToBlock(block, (uint8_t *)&tlv, sizeof(tlv), 0);
211 APPSPAWN_CHECK(ret == 0, return ret, "Failed to add tlv for %{public}d", tlvType);
212
213 for (uint32_t index = 0; index < count; index++) {
214 ret = AddAppDataToBlock(block, (uint8_t *)data[index].data, data[index].dataLen, data[index].dataType);
215 APPSPAWN_CHECK(ret == 0, return ret, "Failed to add data for %{public}d", tlvType);
216 }
217 } else {
218 // 没有一个可用的block,最队列最后添加数据
219 ret = AddAppDataToTail(reqNode, (uint8_t *)&tlv, sizeof(tlv), 0);
220 APPSPAWN_CHECK(ret == 0, return ret, "Failed to add tlv to tail for %{public}d", tlvType);
221 // 添加tlv信息
222 for (uint32_t index = 0; index < count; index++) {
223 ret = AddAppDataToTail(reqNode, (uint8_t *)data[index].data, data[index].dataLen, data[index].dataType);
224 APPSPAWN_CHECK(ret == 0, return ret, "Failed to add data for %{public}d", tlvType);
225 }
226 }
227 reqNode->msg->msgLen += tlv.tlvLen;
228 APPSPAWN_LOGV("AddAppData success tlvType %{public}s end: %{public}u", name, reqNode->msg->msgLen);
229 return 0;
230 }
231
SetFlagsTlv(AppSpawnReqMsgNode * reqNode,AppSpawnMsgBlock * block,AppSpawnMsgFlags ** msgFlags,int type,int maxCount)232 static int SetFlagsTlv(AppSpawnReqMsgNode *reqNode,
233 AppSpawnMsgBlock *block, AppSpawnMsgFlags **msgFlags, int type, int maxCount)
234 {
235 uint32_t units = (uint32_t)CalcFlagsUnits(maxCount);
236 APPSPAWN_LOGV("SetFlagsTlv maxCount %{public}d type %{public}d units %{public}d", maxCount, type, units);
237 uint32_t flagsLen = sizeof(AppSpawnTlv) + sizeof(AppSpawnMsgFlags) + sizeof(uint32_t) * units;
238 APPSPAWN_CHECK((block->blockSize - block->currentIndex) > flagsLen,
239 return APPSPAWN_BUFFER_NOT_ENOUGH, "Invalid block to set flags tlv type %{public}d", type);
240
241 AppSpawnTlv *tlv = (AppSpawnTlv *)(block->buffer + block->currentIndex);
242 tlv->tlvLen = flagsLen;
243 tlv->tlvType = type;
244 *msgFlags = (AppSpawnMsgFlags *)(block->buffer + block->currentIndex + sizeof(AppSpawnTlv));
245 (*msgFlags)->count = units;
246 block->currentIndex += flagsLen;
247 reqNode->msg->msgLen += flagsLen;
248 reqNode->msg->tlvCount++;
249 return 0;
250 }
251
CreateBaseMsg(AppSpawnReqMsgNode * reqNode,uint32_t msgType,const char * processName)252 static int CreateBaseMsg(AppSpawnReqMsgNode *reqNode, uint32_t msgType, const char *processName)
253 {
254 AppSpawnMsgBlock *block = CreateAppSpawnMsgBlock(reqNode);
255 APPSPAWN_CHECK(block != NULL, return APPSPAWN_SYSTEM_ERROR, "Failed to create block for %{public}s", processName);
256
257 // 保留消息头的大小
258 reqNode->msg = (AppSpawnMsg *)(block->buffer + block->currentIndex);
259 reqNode->msg->magic = APPSPAWN_MSG_MAGIC;
260 reqNode->msg->msgId = 0;
261 reqNode->msg->msgType = msgType;
262 reqNode->msg->msgLen = sizeof(AppSpawnMsg);
263 reqNode->msg->tlvCount = 0;
264 int ret = strcpy_s(reqNode->msg->processName, sizeof(reqNode->msg->processName), processName);
265 APPSPAWN_CHECK(ret == 0, return APPSPAWN_SYSTEM_ERROR, "Failed to create block for %{public}s", processName);
266 block->currentIndex = sizeof(AppSpawnMsg);
267 ret = SetFlagsTlv(reqNode, block, &reqNode->msgFlags, TLV_MSG_FLAGS, MAX_FLAGS_INDEX);
268 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
269 APPSPAWN_CHECK_ONLY_EXPER(msgType == MSG_APP_SPAWN || msgType == MSG_SPAWN_NATIVE_PROCESS, return 0);
270 int maxCount = GetPermissionMaxCount();
271 APPSPAWN_CHECK(maxCount > 0, return APPSPAWN_SYSTEM_ERROR, "Invalid max for permission %{public}s", processName);
272 ret = SetFlagsTlv(reqNode, block, &reqNode->permissionFlags, TLV_PERMISSION, maxCount);
273 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
274 APPSPAWN_LOGV("CreateBaseMsg msgLen: %{public}u %{public}u", reqNode->msg->msgLen, block->currentIndex);
275 return 0;
276 }
277
DeleteAppSpawnReqMsg(AppSpawnReqMsgNode * reqNode)278 static void DeleteAppSpawnReqMsg(AppSpawnReqMsgNode *reqNode)
279 {
280 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return);
281 APPSPAWN_LOGV("DeleteAppSpawnReqMsg reqId: %{public}u", reqNode->reqId);
282 reqNode->msgFlags = NULL;
283 reqNode->permissionFlags = NULL;
284 reqNode->msg = NULL;
285 // 释放block
286 OH_ListRemoveAll(&reqNode->msgBlocks, FreeMsgBlock);
287 free(reqNode);
288 }
289
CreateAppSpawnReqMsg(uint32_t msgType,const char * processName)290 static AppSpawnReqMsgNode *CreateAppSpawnReqMsg(uint32_t msgType, const char *processName)
291 {
292 static uint32_t reqId = 0;
293 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)malloc(sizeof(AppSpawnReqMsgNode));
294 APPSPAWN_CHECK(reqNode != NULL, return NULL, "Failed to create msg node for %{public}s", processName);
295
296 OH_ListInit(&reqNode->node);
297 OH_ListInit(&reqNode->msgBlocks);
298 reqNode->reqId = ++reqId;
299 reqNode->msg = NULL;
300 reqNode->msgFlags = NULL;
301 reqNode->permissionFlags = NULL;
302 reqNode->fdCount = 0;
303 reqNode->isAsan = 0;
304 int ret = CreateBaseMsg(reqNode, msgType, processName);
305 APPSPAWN_CHECK(ret == 0, DeleteAppSpawnReqMsg(reqNode);
306 return NULL, "Failed to create base msg for %{public}s", processName);
307 APPSPAWN_LOGV("CreateAppSpawnReqMsg reqId: %{public}d msg type: %{public}u processName: %{public}s",
308 reqNode->reqId, msgType, processName);
309 return reqNode;
310 }
311
AppSpawnReqMsgAddFd(AppSpawnReqMsgHandle reqHandle,const char * fdName,int fd)312 int AppSpawnReqMsgAddFd(AppSpawnReqMsgHandle reqHandle, const char* fdName, int fd)
313 {
314 APPSPAWN_CHECK(reqHandle != NULL, return APPSPAWN_ARG_INVALID, "Invalid reqHandle");
315 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
316 APPSPAWN_CHECK(reqNode != NULL, return APPSPAWN_ARG_INVALID, "Invalid reqNode");
317 APPSPAWN_CHECK(fd >= 0 && fdName != NULL && strlen(fdName) <= APP_FDNAME_MAXLEN
318 && reqNode->fdCount < APP_MAX_FD_COUNT, return APPSPAWN_ARG_INVALID,
319 "Invalid fdinfo %{public}d %{public}d %{public}d", fd, fdName != NULL, reqNode->fdCount);
320 reqNode->fds[reqNode->fdCount++] = fd;
321 return AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_APP_FD, (void *)fdName);
322 }
323
GetSpecialGid(const char * bundleName,gid_t gidTable[],uint32_t * gidCount)324 static void GetSpecialGid(const char *bundleName, gid_t gidTable[], uint32_t *gidCount)
325 {
326 // special handle bundle name medialibrary and scanner
327 const char *specialBundleNames[] = {
328 "com.ohos.medialibrary.medialibrarydata", "com.ohos.medialibrary.medialibrarydata:backup"
329 };
330
331 for (size_t i = 0; i < sizeof(specialBundleNames) / sizeof(specialBundleNames[0]); i++) {
332 if (strcmp(bundleName, specialBundleNames[i]) == 0) {
333 if (*gidCount < APP_MAX_GIDS) {
334 gidTable[(*gidCount)++] = GID_USER_DATA_RW;
335 gidTable[(*gidCount)++] = GID_FILE_ACCESS;
336 }
337 break;
338 }
339 }
340 }
341
AppSpawnReqMsgCreate(AppSpawnMsgType msgType,const char * processName,AppSpawnReqMsgHandle * reqHandle)342 int AppSpawnReqMsgCreate(AppSpawnMsgType msgType, const char *processName, AppSpawnReqMsgHandle *reqHandle)
343 {
344 APPSPAWN_CHECK(reqHandle != NULL, return APPSPAWN_ARG_INVALID, "Invalid request handle");
345 APPSPAWN_CHECK(msgType < MAX_TYPE_INVALID,
346 return APPSPAWN_MSG_INVALID, "Invalid message type %{public}u %{public}s", msgType, processName);
347 int ret = CheckInputString("processName", processName, APP_LEN_PROC_NAME);
348 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
349 AppSpawnReqMsgNode *reqNode = CreateAppSpawnReqMsg(msgType, processName);
350 APPSPAWN_CHECK(reqNode != NULL, return APPSPAWN_SYSTEM_ERROR,
351 "Failed to create msg node for %{public}s", processName);
352 *reqHandle = (AppSpawnReqMsgHandle)(reqNode);
353 return 0;
354 }
355
AppSpawnReqMsgFree(AppSpawnReqMsgHandle reqHandle)356 void AppSpawnReqMsgFree(AppSpawnReqMsgHandle reqHandle)
357 {
358 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
359 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return);
360 DeleteAppSpawnReqMsg(reqNode);
361 }
362
AppSpawnReqMsgSetAppDacInfo(AppSpawnReqMsgHandle reqHandle,const AppDacInfo * dacInfo)363 int AppSpawnReqMsgSetAppDacInfo(AppSpawnReqMsgHandle reqHandle, const AppDacInfo *dacInfo)
364 {
365 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
366 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return APPSPAWN_ARG_INVALID);
367 APPSPAWN_CHECK(dacInfo != NULL, return APPSPAWN_ARG_INVALID, "Invalid dacInfo ");
368
369 AppDacInfo tmpDacInfo = {0};
370 (void)memcpy_s(&tmpDacInfo, sizeof(tmpDacInfo), dacInfo, sizeof(tmpDacInfo));
371 GetSpecialGid(reqNode->msg->processName, tmpDacInfo.gidTable, &tmpDacInfo.gidCount);
372
373 AppSpawnAppData data[MAX_DATA_IN_TLV] = {};
374 data[0].data = (uint8_t *)&tmpDacInfo;
375 data[0].dataLen = sizeof(AppSpawnMsgDacInfo);
376 return AddAppData(reqNode, TLV_DAC_INFO, data, 1, "TLV_DAC_INFO");
377 }
378
AppSpawnReqMsgSetBundleInfo(AppSpawnReqMsgHandle reqHandle,uint32_t bundleIndex,const char * bundleName)379 int AppSpawnReqMsgSetBundleInfo(AppSpawnReqMsgHandle reqHandle, uint32_t bundleIndex, const char *bundleName)
380 {
381 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
382 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return APPSPAWN_ARG_INVALID);
383 int ret = CheckInputString("TLV_BUNDLE_INFO", bundleName, APP_LEN_BUNDLE_NAME);
384 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
385
386 AppSpawnMsgBundleInfo info = {};
387 info.bundleIndex = bundleIndex;
388 AppSpawnAppData data[MAX_DATA_IN_TLV] = {};
389 data[0].data = (uint8_t *)&info;
390 data[0].dataLen = sizeof(AppSpawnMsgBundleInfo);
391 data[1].data = (uint8_t *)bundleName;
392 data[1].dataLen = strlen(bundleName);
393 data[1].dataType = DATA_TYPE_STRING;
394 return AddAppData(reqNode, TLV_BUNDLE_INFO, data, MAX_DATA_IN_TLV, "TLV_BUNDLE_INFO");
395 }
396
CheckEnabled(const char * param,const char * value)397 static int CheckEnabled(const char *param, const char *value)
398 {
399 char tmp[32] = {0}; // 32 max
400 int ret = GetParameter(param, "", tmp, sizeof(tmp));
401 APPSPAWN_LOGV("CheckEnabled key %{public}s ret %{public}d result: %{public}s", param, ret, tmp);
402 int enabled = (ret > 0 && strcmp(tmp, value) == 0);
403 return enabled;
404 }
405
AppSpawnReqMsgSetAppFlag(AppSpawnReqMsgHandle reqHandle,AppFlagsIndex flagIndex)406 int AppSpawnReqMsgSetAppFlag(AppSpawnReqMsgHandle reqHandle, AppFlagsIndex flagIndex)
407 {
408 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
409 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return APPSPAWN_ARG_INVALID);
410 APPSPAWN_CHECK(reqNode->msgFlags != NULL, return APPSPAWN_ARG_INVALID, "No msg flags tlv ");
411 APPSPAWN_CHECK(flagIndex < MAX_FLAGS_INDEX, return APPSPAWN_ARG_INVALID,
412 "Invalid msg app flags %{public}d", flagIndex);
413 if (!reqNode->isAsan &&
414 (flagIndex == APP_FLAGS_UBSAN_ENABLED || flagIndex == APP_FLAGS_ASANENABLED ||
415 flagIndex == APP_FLAGS_TSAN_ENABLED || flagIndex == APP_FLAGS_HWASAN_ENABLED ||
416 (flagIndex == APP_FLAGS_COLD_BOOT && CheckEnabled("startup.appspawn.cold.boot", "true")))) {
417 reqNode->isAsan = 1;
418 }
419
420 return SetAppSpawnMsgFlags(reqNode->msgFlags, flagIndex);
421 }
422
AppSpawnReqMsgAddExtInfo(AppSpawnReqMsgHandle reqHandle,const char * name,const uint8_t * value,uint32_t valueLen)423 int AppSpawnReqMsgAddExtInfo(AppSpawnReqMsgHandle reqHandle, const char *name, const uint8_t *value, uint32_t valueLen)
424 {
425 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
426 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return APPSPAWN_ARG_INVALID);
427 int ret = CheckInputString("check name", name, APPSPAWN_TLV_NAME_LEN);
428 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
429 APPSPAWN_CHECK(value != NULL && valueLen <= EXTRAINFO_TOTAL_LENGTH_MAX && valueLen > 0,
430 return APPSPAWN_ARG_INVALID, "Invalid ext value ");
431
432 APPSPAWN_LOGV("AppSpawnReqMsgAddExtInfo name %{public}s", name);
433 AppSpawnAppData data[1] = {}; // 1 max data count
434 data[0].data = (uint8_t *)value;
435 data[0].dataLen = valueLen;
436 return AddAppDataEx(reqNode, name, data); // 2 max count
437 }
438
AppSpawnReqMsgAddStringInfo(AppSpawnReqMsgHandle reqHandle,const char * name,const char * value)439 int AppSpawnReqMsgAddStringInfo(AppSpawnReqMsgHandle reqHandle, const char *name, const char *value)
440 {
441 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
442 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return APPSPAWN_ARG_INVALID);
443 int ret = CheckInputString("check name", name, APPSPAWN_TLV_NAME_LEN);
444 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
445 ret = CheckInputString(name, value, EXTRAINFO_TOTAL_LENGTH_MAX);
446 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
447
448 APPSPAWN_LOGV("AppSpawnReqMsgAddStringInfo name %{public}s", name);
449 AppSpawnAppData data[1] = {}; // 1 max data count
450 data[0].data = (uint8_t *)value;
451 data[0].dataLen = strlen(value);
452 data[0].dataType = DATA_TYPE_STRING;
453 return AddAppDataEx(reqNode, name, data); // 2 max count
454 }
455
AppSpawnReqMsgAddPermission(AppSpawnReqMsgHandle reqHandle,const char * permission)456 int AppSpawnReqMsgAddPermission(AppSpawnReqMsgHandle reqHandle, const char *permission)
457 {
458 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
459 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return APPSPAWN_ARG_INVALID);
460 APPSPAWN_CHECK(permission != NULL, return APPSPAWN_ARG_INVALID, "Invalid permission ");
461 APPSPAWN_CHECK(reqNode->permissionFlags != NULL, return APPSPAWN_ARG_INVALID, "No permission tlv ");
462
463 int32_t maxIndex = GetMaxPermissionIndex(NULL);
464 int index = GetPermissionIndex(NULL, permission);
465 APPSPAWN_CHECK(index >= 0 && index < maxIndex,
466 return APPSPAWN_PERMISSION_NOT_SUPPORT, "Invalid permission %{public}s", permission);
467 APPSPAWN_LOGV("AddPermission index %{public}d name %{public}s", index, permission);
468 int ret = SetAppSpawnMsgFlags(reqNode->permissionFlags, index);
469 APPSPAWN_CHECK(ret == 0, return ret, "Invalid permission %{public}s", permission);
470 return 0;
471 }
472
AppSpawnReqMsgSetAppDomainInfo(AppSpawnReqMsgHandle reqHandle,uint32_t hapFlags,const char * apl)473 int AppSpawnReqMsgSetAppDomainInfo(AppSpawnReqMsgHandle reqHandle, uint32_t hapFlags, const char *apl)
474 {
475 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
476 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return APPSPAWN_ARG_INVALID);
477 int ret = CheckInputString("TLV_DOMAIN_INFO", apl, APP_APL_MAX_LEN);
478 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
479
480 AppSpawnMsgDomainInfo msgDomainInfo;
481 msgDomainInfo.hapFlags = hapFlags;
482 AppSpawnAppData data[MAX_DATA_IN_TLV] = {};
483 data[0].data = (uint8_t *)&msgDomainInfo;
484 data[0].dataLen = sizeof(AppSpawnMsgDomainInfo);
485 data[1].data = (uint8_t *)apl;
486 data[1].dataLen = strlen(apl);
487 data[1].dataType = DATA_TYPE_STRING;
488 return AddAppData(reqNode, TLV_DOMAIN_INFO, data, MAX_DATA_IN_TLV, "TLV_DOMAIN_INFO");
489 }
490
AppSpawnReqMsgSetAppInternetPermissionInfo(AppSpawnReqMsgHandle reqHandle,uint8_t allow,uint8_t setAllow)491 int AppSpawnReqMsgSetAppInternetPermissionInfo(AppSpawnReqMsgHandle reqHandle, uint8_t allow, uint8_t setAllow)
492 {
493 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
494 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return APPSPAWN_ARG_INVALID);
495
496 AppSpawnMsgInternetInfo info = {};
497 info.allowInternet = allow;
498 info.setAllowInternet = setAllow;
499 AppSpawnAppData data[MAX_DATA_IN_TLV] = {};
500 data[0].data = (uint8_t *)&info;
501 data[0].dataLen = sizeof(AppSpawnMsgInternetInfo);
502 return AddAppData(reqNode, TLV_INTERNET_INFO, data, 1, "TLV_INTERNET_INFO");
503 }
504
AppSpawnReqMsgSetAppOwnerId(AppSpawnReqMsgHandle reqHandle,const char * ownerId)505 int AppSpawnReqMsgSetAppOwnerId(AppSpawnReqMsgHandle reqHandle, const char *ownerId)
506 {
507 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
508 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return APPSPAWN_ARG_INVALID);
509 int ret = CheckInputString("TLV_OWNER_INFO", ownerId, APP_OWNER_ID_LEN);
510 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
511
512 AppSpawnAppData data[MAX_DATA_IN_TLV] = {};
513 data[0].data = (uint8_t *)ownerId;
514 data[0].dataLen = strlen(ownerId);
515 data[0].dataType = DATA_TYPE_STRING;
516 return AddAppData(reqNode, TLV_OWNER_INFO, data, 1, "TLV_OWNER_INFO");
517 }
518
AppSpawnReqMsgSetAppAccessToken(AppSpawnReqMsgHandle reqHandle,uint64_t accessTokenIdEx)519 int AppSpawnReqMsgSetAppAccessToken(AppSpawnReqMsgHandle reqHandle, uint64_t accessTokenIdEx)
520 {
521 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
522 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return APPSPAWN_ARG_INVALID);
523
524 AppSpawnAppData data[MAX_DATA_IN_TLV] = {};
525 data[0].data = (uint8_t *)&accessTokenIdEx;
526 data[0].dataLen = sizeof(accessTokenIdEx);
527 return AddAppData(reqNode, TLV_ACCESS_TOKEN_INFO, data, 1, "TLV_ACCESS_TOKEN_INFO");
528 }
529
AppSpawnTerminateMsgCreate(pid_t pid,AppSpawnReqMsgHandle * reqHandle)530 int AppSpawnTerminateMsgCreate(pid_t pid, AppSpawnReqMsgHandle *reqHandle)
531 {
532 APPSPAWN_CHECK(reqHandle != NULL, return APPSPAWN_ARG_INVALID, "Invalid request handle");
533 AppSpawnReqMsgNode *reqNode = CreateAppSpawnReqMsg(MSG_GET_RENDER_TERMINATION_STATUS, "terminate-process");
534 APPSPAWN_CHECK(reqNode != NULL, return APPSPAWN_SYSTEM_ERROR, "Failed to create msg node");
535
536 AppSpawnAppData data[MAX_DATA_IN_TLV] = {};
537 data[0].data = (uint8_t *)&pid;
538 data[0].dataLen = sizeof(pid);
539 int ret = AddAppData(reqNode, TLV_RENDER_TERMINATION_INFO, data, 1, "TLV_RENDER_TERMINATION_INFO");
540 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, DeleteAppSpawnReqMsg(reqNode);
541 return ret);
542 *reqHandle = (AppSpawnReqMsgHandle)(reqNode);
543 return 0;
544 }
545
AppSpawnClientAddPermission(AppSpawnClientHandle handle,AppSpawnReqMsgHandle reqHandle,const char * permission)546 int AppSpawnClientAddPermission(AppSpawnClientHandle handle, AppSpawnReqMsgHandle reqHandle, const char *permission)
547 {
548 AppSpawnReqMsgMgr *reqMgr = (AppSpawnReqMsgMgr *)handle;
549 APPSPAWN_CHECK(reqMgr != NULL, return APPSPAWN_ARG_INVALID, "Invalid reqMgr");
550 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
551 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return APPSPAWN_ARG_INVALID);
552 APPSPAWN_CHECK(permission != NULL, return APPSPAWN_ARG_INVALID, "Invalid permission ");
553 APPSPAWN_CHECK(reqNode->permissionFlags != NULL, return APPSPAWN_ARG_INVALID, "No permission tlv ");
554
555 int32_t maxIndex = GetMaxPermissionIndex(handle);
556 int index = GetPermissionIndex(handle, permission);
557 APPSPAWN_CHECK(index >= 0 && index < maxIndex,
558 return APPSPAWN_PERMISSION_NOT_SUPPORT, "Invalid permission %{public}s", permission);
559 APPSPAWN_LOGV("add permission index %{public}d name %{public}s", index, permission);
560 int ret = SetAppSpawnMsgFlags(reqNode->permissionFlags, index);
561 APPSPAWN_CHECK(ret == 0, return ret, "Invalid permission %{public}s", permission);
562 return 0;
563 }
564