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