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 23static inline int CalcFlagsUnits(uint32_t maxIndex) 24{ 25 return ((maxIndex / 32) + ((maxIndex % 32 == 0) ? 0 : 1)); // 32 max bit in uint32_t 26} 27 28static 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 38static 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 53static 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 62static 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 73static 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 87static 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 97static 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 105static 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 121static 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 150static 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 188static 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 232static 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 252static 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 278static 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 290static 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 312int 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 324static 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 342int 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 356void AppSpawnReqMsgFree(AppSpawnReqMsgHandle reqHandle) 357{ 358 AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle; 359 APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return); 360 DeleteAppSpawnReqMsg(reqNode); 361} 362 363int 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 379int 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 397static 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 406int 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 423int 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 439int 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 456int 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 473int 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 491int 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 505int 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 519int 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 530int 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 546int 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