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 = 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 int ret = CreateBaseMsg(reqNode, msgType, processName);
303 APPSPAWN_CHECK(ret == 0, DeleteAppSpawnReqMsg(reqNode);
304 return NULL, "Failed to create base msg for %{public}s", processName);
305 APPSPAWN_LOGV("CreateAppSpawnReqMsg reqId: %{public}d msg type: %{public}u processName: %{public}s",
306 reqNode->reqId, msgType, processName);
307 return reqNode;
308 }
309
GetSpecialGid(const char * bundleName,gid_t gidTable[],uint32_t * gidCount)310 static void GetSpecialGid(const char *bundleName, gid_t gidTable[], uint32_t *gidCount)
311 {
312 // special handle bundle name medialibrary and scanner
313 const char *specialBundleNames[] = {
314 "com.ohos.medialibrary.medialibrarydata", "com.ohos.medialibrary.medialibrarydata:backup"
315 };
316
317 for (size_t i = 0; i < sizeof(specialBundleNames) / sizeof(specialBundleNames[0]); i++) {
318 if (strcmp(bundleName, specialBundleNames[i]) == 0) {
319 if (*gidCount < APP_MAX_GIDS) {
320 gidTable[(*gidCount)++] = GID_USER_DATA_RW;
321 gidTable[(*gidCount)++] = GID_FILE_ACCESS;
322 }
323 break;
324 }
325 }
326 }
327
AppSpawnReqMsgCreate(AppSpawnMsgType msgType,const char * processName,AppSpawnReqMsgHandle * reqHandle)328 int AppSpawnReqMsgCreate(AppSpawnMsgType msgType, const char *processName, AppSpawnReqMsgHandle *reqHandle)
329 {
330 APPSPAWN_CHECK(reqHandle != NULL, return APPSPAWN_ARG_INVALID, "Invalid request handle");
331 APPSPAWN_CHECK(msgType < MAX_TYPE_INVALID,
332 return APPSPAWN_MSG_INVALID, "Invalid message type %{public}u %{public}s", msgType, processName);
333 int ret = CheckInputString("processName", processName, APP_LEN_PROC_NAME);
334 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
335 AppSpawnReqMsgNode *reqNode = CreateAppSpawnReqMsg(msgType, processName);
336 APPSPAWN_CHECK(reqNode != NULL, return APPSPAWN_SYSTEM_ERROR,
337 "Failed to create msg node for %{public}s", processName);
338 *reqHandle = (AppSpawnReqMsgHandle)(reqNode);
339 return 0;
340 }
341
AppSpawnReqMsgFree(AppSpawnReqMsgHandle reqHandle)342 void AppSpawnReqMsgFree(AppSpawnReqMsgHandle reqHandle)
343 {
344 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
345 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return);
346 DeleteAppSpawnReqMsg(reqNode);
347 }
348
AppSpawnReqMsgSetAppDacInfo(AppSpawnReqMsgHandle reqHandle,const AppDacInfo * dacInfo)349 int AppSpawnReqMsgSetAppDacInfo(AppSpawnReqMsgHandle reqHandle, const AppDacInfo *dacInfo)
350 {
351 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
352 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return APPSPAWN_ARG_INVALID);
353 APPSPAWN_CHECK(dacInfo != NULL, return APPSPAWN_ARG_INVALID, "Invalid dacInfo ");
354
355 AppDacInfo tmpDacInfo = {0};
356 (void)memcpy_s(&tmpDacInfo, sizeof(tmpDacInfo), dacInfo, sizeof(tmpDacInfo));
357 GetSpecialGid(reqNode->msg->processName, tmpDacInfo.gidTable, &tmpDacInfo.gidCount);
358
359 AppSpawnAppData data[MAX_DATA_IN_TLV] = {};
360 data[0].data = (uint8_t *)&tmpDacInfo;
361 data[0].dataLen = sizeof(AppSpawnMsgDacInfo);
362 return AddAppData(reqNode, TLV_DAC_INFO, data, 1, "TLV_DAC_INFO");
363 }
364
AppSpawnReqMsgSetBundleInfo(AppSpawnReqMsgHandle reqHandle,uint32_t bundleIndex,const char * bundleName)365 int AppSpawnReqMsgSetBundleInfo(AppSpawnReqMsgHandle reqHandle, uint32_t bundleIndex, const char *bundleName)
366 {
367 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
368 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return APPSPAWN_ARG_INVALID);
369 int ret = CheckInputString("TLV_BUNDLE_INFO", bundleName, APP_LEN_BUNDLE_NAME);
370 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
371
372 AppSpawnMsgBundleInfo info = {};
373 info.bundleIndex = bundleIndex;
374 AppSpawnAppData data[MAX_DATA_IN_TLV] = {};
375 data[0].data = (uint8_t *)&info;
376 data[0].dataLen = sizeof(AppSpawnMsgBundleInfo);
377 data[1].data = (uint8_t *)bundleName;
378 data[1].dataLen = strlen(bundleName);
379 data[1].dataType = DATA_TYPE_STRING;
380 return AddAppData(reqNode, TLV_BUNDLE_INFO, data, MAX_DATA_IN_TLV, "TLV_BUNDLE_INFO");
381 }
382
AppSpawnReqMsgSetAppFlag(AppSpawnReqMsgHandle reqHandle,AppFlagsIndex flagIndex)383 int AppSpawnReqMsgSetAppFlag(AppSpawnReqMsgHandle reqHandle, AppFlagsIndex flagIndex)
384 {
385 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
386 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return APPSPAWN_ARG_INVALID);
387 APPSPAWN_CHECK(reqNode->msgFlags != NULL, return APPSPAWN_ARG_INVALID, "No msg flags tlv ");
388 APPSPAWN_CHECK(flagIndex < MAX_FLAGS_INDEX, return APPSPAWN_ARG_INVALID,
389 "Invalid msg app flags %{public}d", flagIndex);
390 return SetAppSpawnMsgFlags(reqNode->msgFlags, flagIndex);
391 }
392
AppSpawnReqMsgAddExtInfo(AppSpawnReqMsgHandle reqHandle,const char * name,const uint8_t * value,uint32_t valueLen)393 int AppSpawnReqMsgAddExtInfo(AppSpawnReqMsgHandle reqHandle, const char *name, const uint8_t *value, uint32_t valueLen)
394 {
395 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
396 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return APPSPAWN_ARG_INVALID);
397 int ret = CheckInputString("check name", name, APPSPAWN_TLV_NAME_LEN);
398 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
399 APPSPAWN_CHECK(value != NULL && valueLen <= EXTRAINFO_TOTAL_LENGTH_MAX && valueLen > 0,
400 return APPSPAWN_ARG_INVALID, "Invalid ext value ");
401
402 APPSPAWN_LOGV("AppSpawnReqMsgAddExtInfo name %{public}s", name);
403 AppSpawnAppData data[1] = {}; // 1 max data count
404 data[0].data = (uint8_t *)value;
405 data[0].dataLen = valueLen;
406 return AddAppDataEx(reqNode, name, data); // 2 max count
407 }
408
AppSpawnReqMsgAddStringInfo(AppSpawnReqMsgHandle reqHandle,const char * name,const char * value)409 int AppSpawnReqMsgAddStringInfo(AppSpawnReqMsgHandle reqHandle, const char *name, const char *value)
410 {
411 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
412 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return APPSPAWN_ARG_INVALID);
413 int ret = CheckInputString("check name", name, APPSPAWN_TLV_NAME_LEN);
414 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
415 ret = CheckInputString(name, value, EXTRAINFO_TOTAL_LENGTH_MAX);
416 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
417
418 APPSPAWN_LOGV("AppSpawnReqMsgAddStringInfo name %{public}s", name);
419 AppSpawnAppData data[1] = {}; // 1 max data count
420 data[0].data = (uint8_t *)value;
421 data[0].dataLen = strlen(value);
422 data[0].dataType = DATA_TYPE_STRING;
423 return AddAppDataEx(reqNode, name, data); // 2 max count
424 }
425
AppSpawnReqMsgAddPermission(AppSpawnReqMsgHandle reqHandle,const char * permission)426 int AppSpawnReqMsgAddPermission(AppSpawnReqMsgHandle reqHandle, const char *permission)
427 {
428 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
429 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return APPSPAWN_ARG_INVALID);
430 APPSPAWN_CHECK(permission != NULL, return APPSPAWN_ARG_INVALID, "Invalid permission ");
431 APPSPAWN_CHECK(reqNode->permissionFlags != NULL, return APPSPAWN_ARG_INVALID, "No permission tlv ");
432
433 int32_t maxIndex = GetMaxPermissionIndex(NULL);
434 int index = GetPermissionIndex(NULL, permission);
435 APPSPAWN_CHECK(index >= 0 && index < maxIndex,
436 return APPSPAWN_PERMISSION_NOT_SUPPORT, "Invalid permission %{public}s", permission);
437 APPSPAWN_LOGV("AddPermission index %{public}d name %{public}s", index, permission);
438 int ret = SetAppSpawnMsgFlags(reqNode->permissionFlags, index);
439 APPSPAWN_CHECK(ret == 0, return ret, "Invalid permission %{public}s", permission);
440 return 0;
441 }
442
AppSpawnReqMsgSetAppDomainInfo(AppSpawnReqMsgHandle reqHandle,uint32_t hapFlags,const char * apl)443 int AppSpawnReqMsgSetAppDomainInfo(AppSpawnReqMsgHandle reqHandle, uint32_t hapFlags, const char *apl)
444 {
445 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
446 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return APPSPAWN_ARG_INVALID);
447 int ret = CheckInputString("TLV_DOMAIN_INFO", apl, APP_APL_MAX_LEN);
448 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
449
450 AppSpawnMsgDomainInfo msgDomainInfo;
451 msgDomainInfo.hapFlags = hapFlags;
452 AppSpawnAppData data[MAX_DATA_IN_TLV] = {};
453 data[0].data = (uint8_t *)&msgDomainInfo;
454 data[0].dataLen = sizeof(AppSpawnMsgDomainInfo);
455 data[1].data = (uint8_t *)apl;
456 data[1].dataLen = strlen(apl);
457 data[1].dataType = DATA_TYPE_STRING;
458 return AddAppData(reqNode, TLV_DOMAIN_INFO, data, MAX_DATA_IN_TLV, "TLV_DOMAIN_INFO");
459 }
460
AppSpawnReqMsgSetAppInternetPermissionInfo(AppSpawnReqMsgHandle reqHandle,uint8_t allow,uint8_t setAllow)461 int AppSpawnReqMsgSetAppInternetPermissionInfo(AppSpawnReqMsgHandle reqHandle, uint8_t allow, uint8_t setAllow)
462 {
463 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
464 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return APPSPAWN_ARG_INVALID);
465
466 AppSpawnMsgInternetInfo info = {};
467 info.allowInternet = allow;
468 info.setAllowInternet = setAllow;
469 AppSpawnAppData data[MAX_DATA_IN_TLV] = {};
470 data[0].data = (uint8_t *)&info;
471 data[0].dataLen = sizeof(AppSpawnMsgInternetInfo);
472 return AddAppData(reqNode, TLV_INTERNET_INFO, data, 1, "TLV_INTERNET_INFO");
473 }
474
AppSpawnReqMsgSetAppOwnerId(AppSpawnReqMsgHandle reqHandle,const char * ownerId)475 int AppSpawnReqMsgSetAppOwnerId(AppSpawnReqMsgHandle reqHandle, const char *ownerId)
476 {
477 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
478 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return APPSPAWN_ARG_INVALID);
479 int ret = CheckInputString("TLV_OWNER_INFO", ownerId, APP_OWNER_ID_LEN);
480 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
481
482 AppSpawnAppData data[MAX_DATA_IN_TLV] = {};
483 data[0].data = (uint8_t *)ownerId;
484 data[0].dataLen = strlen(ownerId);
485 data[0].dataType = DATA_TYPE_STRING;
486 return AddAppData(reqNode, TLV_OWNER_INFO, data, 1, "TLV_OWNER_INFO");
487 }
488
AppSpawnReqMsgSetAppAccessToken(AppSpawnReqMsgHandle reqHandle,uint64_t accessTokenIdEx)489 int AppSpawnReqMsgSetAppAccessToken(AppSpawnReqMsgHandle reqHandle, uint64_t accessTokenIdEx)
490 {
491 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
492 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return APPSPAWN_ARG_INVALID);
493
494 AppSpawnAppData data[MAX_DATA_IN_TLV] = {};
495 data[0].data = (uint8_t *)&accessTokenIdEx;
496 data[0].dataLen = sizeof(accessTokenIdEx);
497 return AddAppData(reqNode, TLV_ACCESS_TOKEN_INFO, data, 1, "TLV_ACCESS_TOKEN_INFO");
498 }
499
AppSpawnTerminateMsgCreate(pid_t pid,AppSpawnReqMsgHandle * reqHandle)500 int AppSpawnTerminateMsgCreate(pid_t pid, AppSpawnReqMsgHandle *reqHandle)
501 {
502 APPSPAWN_CHECK(reqHandle != NULL, return APPSPAWN_ARG_INVALID, "Invalid request handle");
503 AppSpawnReqMsgNode *reqNode = CreateAppSpawnReqMsg(MSG_GET_RENDER_TERMINATION_STATUS, "terminate-process");
504 APPSPAWN_CHECK(reqNode != NULL, return APPSPAWN_SYSTEM_ERROR, "Failed to create msg node");
505
506 AppSpawnAppData data[MAX_DATA_IN_TLV] = {};
507 data[0].data = (uint8_t *)&pid;
508 data[0].dataLen = sizeof(pid);
509 int ret = AddAppData(reqNode, TLV_RENDER_TERMINATION_INFO, data, 1, "TLV_RENDER_TERMINATION_INFO");
510 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, DeleteAppSpawnReqMsg(reqNode);
511 return ret);
512 *reqHandle = (AppSpawnReqMsgHandle)(reqNode);
513 return 0;
514 }
515
AppSpawnClientAddPermission(AppSpawnClientHandle handle,AppSpawnReqMsgHandle reqHandle,const char * permission)516 int AppSpawnClientAddPermission(AppSpawnClientHandle handle, AppSpawnReqMsgHandle reqHandle, const char *permission)
517 {
518 AppSpawnReqMsgMgr *reqMgr = (AppSpawnReqMsgMgr *)handle;
519 APPSPAWN_CHECK(reqMgr != NULL, return APPSPAWN_ARG_INVALID, "Invalid reqMgr");
520 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
521 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return APPSPAWN_ARG_INVALID);
522 APPSPAWN_CHECK(permission != NULL, return APPSPAWN_ARG_INVALID, "Invalid permission ");
523 APPSPAWN_CHECK(reqNode->permissionFlags != NULL, return APPSPAWN_ARG_INVALID, "No permission tlv ");
524
525 int32_t maxIndex = GetMaxPermissionIndex(handle);
526 int index = GetPermissionIndex(handle, permission);
527 APPSPAWN_CHECK(index >= 0 && index < maxIndex,
528 return APPSPAWN_PERMISSION_NOT_SUPPORT, "Invalid permission %{public}s", permission);
529 APPSPAWN_LOGV("add permission index %{public}d name %{public}s", index, permission);
530 int ret = SetAppSpawnMsgFlags(reqNode->permissionFlags, index);
531 APPSPAWN_CHECK(ret == 0, return ret, "Invalid permission %{public}s", permission);
532 return 0;
533 }
534