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