• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "form_module_checker.h"
17 
18 #include <functional>
19 #include <memory>
20 #include <string>
21 #include <vector>
22 #include <fstream>
23 #include <filesystem>
24 
25 #include "fms_log_wrapper.h"
26 #include "nlohmann/json.hpp"
27 #include "config_policy_utils.h"
28 
29 namespace {
30 const std::string FORM_MODULE_WHITE_LIST_PATH = "/etc/form_fwk_module_white_list.json";
31 const std::string KEY_MODULE_ALLOW = "moduleAllowList";
32 const std::vector<std::string> MODULE_ALLOW_LIST = {
33     "mediaquery",
34     "display",
35     "effectKit",
36     "arkui.shape",
37     "hilog",
38     "url",
39     "util",
40     "util.ArrayList",
41     "util.HashMap",
42     "util.List",
43     "util.json",
44     "animator",
45     "measure",
46     "intl",
47     "systemDateTime",
48     "batteryInfo",
49     "commonEventManager"
50 };
51 const std::vector<std::string> MODULE_ALLOW_WITH_API_LIST = {
52     "i18n",
53     "font",
54     "multimedia.image",
55     "deviceInfo",
56     "window",
57     "process"
58 };
59 const std::vector<std::string> API_ALLOW_LIST = {
60     "i18n.System.getSystemLanguage",
61     "i18n.System.is24HourClock",
62     "i18n.System.getSystemLocale",
63     "i18n.System.getSystemRegion",
64     "i18n.isRTL",
65     "i18n.getTimeZone",
66     "i18n.getCalendar"
67     "i18n.Calendar.*",
68     "i18n.TimeZone.*",
69     "i18n.Unicode.*",
70     "font.registerFont",
71     "multimedia.image.PixelMapFormat.*",
72     "multimedia.image.Size.*",
73     "multimedia.image.AlphaType.*",
74     "multimedia.image.ScaleMode.*",
75     "multimedia.image.Region.*",
76     "multimedia.image.PositionArea.*",
77     "multimedia.image.ImageInfo.*",
78     "multimedia.image.DecodingOptions.*",
79     "multimedia.image.InitializationOptions.*",
80     "multimedia.image.SourceOptions.*",
81     "multimedia.image.createImageSource",
82     "multimedia.image.PixelMap.*",
83     "multimedia.image.ImageSource.*",
84     "deviceInfo.deviceType",
85     "deviceInfo.productModel",
86     "window.WindowType.*",
87     "window.AvoidAreaType.*",
88     "window.WindowMode.*",
89     "window.ColorSpace.*",
90     "window.WindowStageEventType.*",
91     "window.WindowEventType.*",
92     "window.WindowLayoutMode.*",
93     "window.Orientation.*",
94     "window.BlurStyle.*",
95     "window.WmErrorCode.*",
96     "window.WMError.*",
97     "window.WindowStatusType.*",
98     "window.RectChangeReason.*",
99     "window.MaximizePresentation.*",
100     "window.ExtensionWindowAttribute.*",
101     "window.ModalityType.*",
102     "window._napiwrapper.*",
103     "window.getTopWindow.*",
104     "window.getLastWindow.*",
105     "process.pid",
106     "process.tid"
107 };
108 } // namespace
109 
110 std::vector<std::string> FormModuleChecker::modulesFromCfg_ = FormModuleChecker::GetModuleAllowList();
111 
CheckApiAllowList(const std::string & apiPath)112 bool FormModuleChecker::CheckApiAllowList(const std::string& apiPath)
113 {
114     for (const auto& item : API_ALLOW_LIST) {
115         if (CheckApiWithSuffix(apiPath, item)) {
116             return true;
117         }
118     }
119 
120     HILOG_ERROR("api not allowed, apiPath: '%{public}s'", apiPath.c_str());
121     return false;
122 }
123 
CheckApiWithSuffix(const std::string & apiPath,const std::string & item)124 bool FormModuleChecker::CheckApiWithSuffix(const std::string& apiPath, const std::string& item)
125 {
126     HILOG_DEBUG("apiPath: '%{public}s', item: '%{public}s'", apiPath.c_str(), item.c_str());
127     if (item.compare(0, apiPath.size(), apiPath) == 0) {
128         return true;
129     }
130     const int32_t kSuffixLength = 2;
131     if (item.size() >= kSuffixLength && item.substr(item.size() - kSuffixLength) == ".*") {
132         const std::string path = item.substr(0, item.rfind('.'));
133         if (apiPath.compare(0, path.size(), path) == 0) {
134             return true;
135         }
136     }
137 
138     return false;
139 }
140 
CheckModuleLoadable(const char * moduleName,std::unique_ptr<ApiAllowListChecker> & apiAllowListChecker,bool isAppModule)141 bool FormModuleChecker::CheckModuleLoadable(const char *moduleName,
142     std::unique_ptr<ApiAllowListChecker> &apiAllowListChecker, bool isAppModule)
143 {
144     if (isAppModule) {
145         HILOG_ERROR("module is not system, moduleName= %{public}s", moduleName);
146         return false;
147     }
148 
149     // only check module
150     for (const auto& item : modulesFromCfg_) {
151         if (item == moduleName) {
152             HILOG_DEBUG("load moduleName= %{public}s", moduleName);
153             return true;
154         }
155     }
156     for (const auto& item : MODULE_ALLOW_LIST) {
157         if (item == moduleName) {
158             HILOG_DEBUG("load moduleName= %{public}s", moduleName);
159             return true;
160         }
161     }
162 
163     // check mnodule and api
164     if (IsModuelAllowToLoad(moduleName)) {
165         HILOG_DEBUG("module has been allowed by the allowlist in form, module name = %{public}s", moduleName);
166         if (apiAllowListChecker == nullptr) {
167             apiAllowListChecker = std::make_unique<ApiAllowListChecker>([](const std::string& apiPath) {
168                 return CheckApiAllowList(apiPath);
169             });
170         }
171         return true;
172     }
173     HILOG_ERROR("module can't load in form,moduleName= %{public}s", moduleName);
174     return false;
175 }
176 
IsModuelAllowToLoad(const std::string & moduleName)177 bool FormModuleChecker::IsModuelAllowToLoad(const std::string& moduleName)
178 {
179     for (const auto& item : MODULE_ALLOW_WITH_API_LIST) {
180         if (item == moduleName) {
181             return true;
182         }
183     }
184 
185     return false;
186 }
187 
GetModuleAllowList()188 std::vector<std::string> FormModuleChecker::GetModuleAllowList()
189 {
190     HILOG_INFO("read moduleAllowList from config file");
191     std::vector<std::string> result;
192     char buf[MAX_PATH_LEN];
193     char* path = GetOneCfgFile(FORM_MODULE_WHITE_LIST_PATH.c_str(), buf, MAX_PATH_LEN);
194     if (path == nullptr || *path == '\0') {
195         HILOG_ERROR("config file not found");
196         return result;
197     }
198     std::ifstream file(path);
199     if (!file.is_open()) {
200         HILOG_ERROR("failed to open config file");
201         return result;
202     }
203     HILOG_INFO("success to open config file");
204     nlohmann::json jsonData;
205     file >> jsonData;
206     if (jsonData.contains(KEY_MODULE_ALLOW) && jsonData[KEY_MODULE_ALLOW].is_array()) {
207         for (const auto& module : jsonData[KEY_MODULE_ALLOW]) {
208             HILOG_INFO("read moduleAllowList module: %{public}s", std::string(module).c_str());
209             result.push_back(module);
210         }
211     }
212     file.close();
213     return result;
214 }
215 
DiskCheckOnly()216 bool FormModuleChecker::DiskCheckOnly()
217 {
218     return false;
219 }
220