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