• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 "app_spawn_msg_wrapper.h"
17 
18 #include "securec.h"
19 
20 #include "hilog_wrapper.h"
21 #include "nlohmann/json.hpp"
22 
23 namespace OHOS {
24 namespace AppExecFwk {
25 namespace {
26     const std::string HSPLIST_BUNDLES = "bundles";
27     const std::string HSPLIST_MODULES = "modules";
28     const std::string HSPLIST_VERSIONS = "versions";
29     const std::string HSPLIST_SOCKET_TYPE = "|HspList|";
30     const std::string OVERLAY_SOCKET_TYPE = "|Overlay|";
31     const std::string DATA_GROUP_SOCKET_TYPE = "|DataGroup|";
32     const std::string DATAGROUPINFOLIST_DATAGROUPID = "dataGroupId";
33     const std::string DATAGROUPINFOLIST_GID = "gid";
34     const std::string DATAGROUPINFOLIST_DIR = "dir";
35     const std::string JSON_DATA_APP = "/data/app/el2/";
36     const std::string JSON_GROUP = "/group/";
37     const std::string VERSION_PREFIX = "v";
38 }
39 
~AppSpawnMsgWrapper()40 AppSpawnMsgWrapper::~AppSpawnMsgWrapper()
41 {
42     FreeMsg();
43 }
44 
DumpToJson(const HspList & hspList)45 static std::string DumpToJson(const HspList &hspList)
46 {
47     nlohmann::json hspListJson;
48     for (auto& hsp : hspList) {
49         hspListJson[HSPLIST_BUNDLES].emplace_back(hsp.bundleName);
50         hspListJson[HSPLIST_MODULES].emplace_back(hsp.moduleName);
51         hspListJson[HSPLIST_VERSIONS].emplace_back(VERSION_PREFIX + std::to_string(hsp.versionCode));
52     }
53     return hspListJson.dump();
54 }
55 
DumpToJson(const DataGroupInfoList & dataGroupInfoList)56 static std::string DumpToJson(const DataGroupInfoList &dataGroupInfoList)
57 {
58     nlohmann::json dataGroupInfoListJson;
59     for (auto& dataGroupInfo : dataGroupInfoList) {
60         dataGroupInfoListJson[DATAGROUPINFOLIST_DATAGROUPID].emplace_back(dataGroupInfo.dataGroupId);
61         dataGroupInfoListJson[DATAGROUPINFOLIST_GID].emplace_back(std::to_string(dataGroupInfo.gid));
62         std::string dir = JSON_DATA_APP + std::to_string(dataGroupInfo.userId)
63             + JSON_GROUP + dataGroupInfo.uuid;
64         dataGroupInfoListJson[DATAGROUPINFOLIST_DIR].emplace_back(dir);
65     }
66     return dataGroupInfoListJson.dump();
67 }
68 
AssembleMsg(const AppSpawnStartMsg & startMsg)69 bool AppSpawnMsgWrapper::AssembleMsg(const AppSpawnStartMsg &startMsg)
70 {
71     if (!VerifyMsg(startMsg)) {
72         return false;
73     }
74     FreeMsg();
75     size_t msgSize = sizeof(AppSpawnMsg) + 1;
76     msg_ = static_cast<AppSpawnMsg *>(malloc(msgSize));
77     if (msg_ == nullptr) {
78         HILOG_ERROR("failed to malloc!");
79         return false;
80     }
81     if (memset_s(msg_, msgSize, 0, msgSize) != EOK) {
82         HILOG_ERROR("failed to memset!");
83         return false;
84     }
85     msg_->code = static_cast<AppSpawn::ClientSocket::AppOperateCode>(startMsg.code);
86     if (msg_->code == AppSpawn::ClientSocket::AppOperateCode::DEFAULT ||
87         msg_->code == AppSpawn::ClientSocket::AppOperateCode::SPAWN_NATIVE_PROCESS) {
88         msg_->uid = startMsg.uid;
89         msg_->gid = startMsg.gid;
90         msg_->gidCount = startMsg.gids.size() + startMsg.dataGroupInfoList.size();
91         msg_->bundleIndex = startMsg.bundleIndex;
92         msg_->setAllowInternet = startMsg.setAllowInternet;
93         msg_->allowInternet = startMsg.allowInternet;
94         msg_->mountPermissionFlags = startMsg.mountPermissionFlags;
95         if (strcpy_s(msg_->ownerId, sizeof(msg_->ownerId), startMsg.ownerId.c_str()) != EOK) {
96             HILOG_ERROR("failed to transform ownerId!");
97             return false;
98         }
99         for (uint32_t i = 0; i < startMsg.gids.size(); ++i) {
100             msg_->gidTable[i] = startMsg.gids[i];
101         }
102         for (uint32_t i = startMsg.gids.size(); i < msg_->gidCount; ++i) {
103             msg_->gidTable[i] = startMsg.dataGroupInfoList[i - startMsg.gids.size()].gid;
104         }
105         if (strcpy_s(msg_->processName, sizeof(msg_->processName), startMsg.procName.c_str()) != EOK) {
106             HILOG_ERROR("failed to transform procName!");
107             return false;
108         }
109         if (strcpy_s(msg_->soPath, sizeof(msg_->soPath), startMsg.soPath.c_str()) != EOK) {
110             HILOG_ERROR("failed to transform soPath!");
111             return false;
112         }
113         msg_->accessTokenId = startMsg.accessTokenId;
114         if (strcpy_s(msg_->apl, sizeof(msg_->apl), startMsg.apl.c_str()) != EOK) {
115             HILOG_ERROR("failed to transform apl!");
116             return false;
117         }
118         if (strcpy_s(msg_->bundleName, sizeof(msg_->bundleName), startMsg.bundleName.c_str()) != EOK) {
119             HILOG_ERROR("failed to transform bundleName!");
120             return false;
121         }
122 
123         if (strcpy_s(msg_->renderCmd, sizeof(msg_->renderCmd), startMsg.renderParam.c_str()) != EOK) {
124             HILOG_ERROR("failed to transform renderCmd!");
125             return false;
126         }
127         msg_->flags = startMsg.flags;
128         msg_->accessTokenIdEx = startMsg.accessTokenIdEx;
129         msg_->hapFlags = startMsg.hapFlags;
130 
131         if (!startMsg.hspList.empty()) {
132             this->extraInfoStr += HSPLIST_SOCKET_TYPE + DumpToJson(startMsg.hspList) +
133                                   HSPLIST_SOCKET_TYPE;
134         }
135 
136         if (!startMsg.dataGroupInfoList.empty()) {
137             this->extraInfoStr += DATA_GROUP_SOCKET_TYPE + DumpToJson(startMsg.dataGroupInfoList) +
138                                   DATA_GROUP_SOCKET_TYPE;
139         }
140 
141         if (!startMsg.overlayInfo.empty()) {
142             this->extraInfoStr += OVERLAY_SOCKET_TYPE + startMsg.overlayInfo +
143                                   OVERLAY_SOCKET_TYPE;
144         }
145         if (!this->extraInfoStr.empty()) {
146             msg_->extraInfo.totalLength = this->extraInfoStr.size() + 1;
147         }
148     } else if (msg_->code == AppSpawn::ClientSocket::AppOperateCode::GET_RENDER_TERMINATION_STATUS) {
149         msg_->pid = startMsg.pid;
150     } else {
151         HILOG_ERROR("invalid code");
152         return false;
153     }
154 
155     isValid_ = true;
156     DumpMsg();
157     return isValid_;
158 }
159 
VerifyMsg(const AppSpawnStartMsg & startMsg) const160 bool AppSpawnMsgWrapper::VerifyMsg(const AppSpawnStartMsg &startMsg) const
161 {
162     if (startMsg.code == AppSpawn::ClientSocket::AppOperateCode::DEFAULT ||
163         startMsg.code == AppSpawn::ClientSocket::AppOperateCode::SPAWN_NATIVE_PROCESS) {
164         if (startMsg.uid < 0) {
165             HILOG_ERROR("invalid uid! [%{public}d]", startMsg.uid);
166             return false;
167         }
168 
169         if (startMsg.gid < 0) {
170             HILOG_ERROR("invalid gid! [%{public}d]", startMsg.gid);
171             return false;
172         }
173 
174         if (startMsg.gids.size() > AppSpawn::ClientSocket::MAX_GIDS) {
175             HILOG_ERROR("too many app gids!");
176             return false;
177         }
178 
179         for (uint32_t i = 0; i < startMsg.gids.size(); ++i) {
180             if (startMsg.gids[i] < 0) {
181                 HILOG_ERROR("invalid gids array! [%{public}d]", startMsg.gids[i]);
182                 return false;
183             }
184         }
185 
186         if (startMsg.procName.empty() || startMsg.procName.size() >= AppSpawn::ClientSocket::LEN_PROC_NAME) {
187             HILOG_ERROR("invalid procName!");
188             return false;
189         }
190     } else if (startMsg.code == AppSpawn::ClientSocket::AppOperateCode::GET_RENDER_TERMINATION_STATUS) {
191         if (startMsg.pid < 0) {
192             HILOG_ERROR("invalid pid!");
193             return false;
194         }
195     } else {
196         HILOG_ERROR("invalid code!");
197         return false;
198     }
199 
200     return true;
201 }
202 
DumpMsg() const203 void AppSpawnMsgWrapper::DumpMsg() const
204 {
205     if (!isValid_) {
206         return;
207     }
208     std::string accessTokenIdExString = std::to_string(msg_->accessTokenIdEx);
209     HILOG_DEBUG("uid: %{public}d, gid: %{public}d, procName: %{public}s, accessTokenIdEx :%{public}s",
210         msg_->uid, msg_->gid, msg_->processName, accessTokenIdExString.c_str());
211 }
212 
FreeMsg()213 void AppSpawnMsgWrapper::FreeMsg()
214 {
215     if (msg_ != nullptr) {
216         free(msg_);
217         msg_ = nullptr;
218         isValid_ = false;
219     }
220 }
221 }  // namespace AppExecFwk
222 }  // namespace OHOS
223