1 /*
2 * Copyright (c) 2022 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 #include <cerrno>
16 #include <unistd.h>
17 #include <sys/stat.h>
18 #include "init_unittest.h"
19 #include "cJSON.h"
20 #include "sandbox.h"
21 #include "sandbox_namespace.h"
22 #include "securec.h"
23
24 using namespace testing::ext;
25 namespace init_ut {
26 const int NULL_ROOT_PATH = 1;
27 const int NULL_MOUNT_FLAGS = 2;
28 const int NULL_MOUNT = 3;
29 const int NULL_MOUNT_ITEM = 13;
30 const int LINK_ARRARY_START = 5;
31 const int LINK_ARRARY_END = 8;
32 const int FLAGS_NUMBER = 3;
33
34 const char *TEST_SANDBOX_NAME = "test";
35 const char *SANDBOX_JSON_NAME = "test-sandbox.json";
36
37 const char *SANDBOX_CONFIG[] = {"sandbox-root", "mount-bind-paths", "mount-bind-files", "symbol-links"};
38 const char *SANDBOX_ROOT[] = { "/mnt/sandbox/test", "/mnt/sandbox/chipset", "/mnt/error"};
39 const char *SANDBOX_FLAGS[] = {"bind", "rec", "private"};
40 const char *MOUNT_BIND_PATHS[] = {"src-path", "sandbox-path", "sandbox-flags"};
41 const char *SYMBOL_LINKS[] = {"target-name", "link-name"};
42 const char *APP_PATHS[] = {"/mnt", "/sys", "/proc", "/dev", "/data",
43 "/system/bin", "/system/lib", "/system/etc", "/system"};
44
RestartSandbox(const char * sandbox)45 int RestartSandbox(const char *sandbox)
46 {
47 if (sandbox == nullptr) {
48 std::cout << "invalid parameters" << std::endl;
49 return 0;
50 }
51 InitDefaultNamespace();
52 std::cout << "init namespace" << std::endl;
53 if (!InitSandboxWithName(sandbox)) {
54 CloseDefaultNamespace();
55 std::cout << "Failed to init sandbox with name " << sandbox << std::endl;
56 return 0;
57 }
58 std::cout << "init sandbox with name" << std::endl;
59 DumpSandboxByName(sandbox);
60 std::cout << "dump sandbox" << std::endl;
61 if (PrepareSandbox(sandbox) != 0) {
62 std::cout << "Failed to prepare sandbox " << sandbox << std::endl;
63 DestroySandbox(sandbox);
64 CloseDefaultNamespace();
65 return 0;
66 }
67 std::cout << "prepare sandbox" << std::endl;
68 if (EnterDefaultNamespace() < 0) {
69 std::cout << "Failed to set default namespace" << std::endl;
70 DestroySandbox(sandbox);
71 CloseDefaultNamespace();
72 return 0;
73 }
74 std::cout << "enter default namespace" << std::endl;
75 CloseDefaultNamespace();
76 std::cout << "close namespace" << std::endl;
77 return 1;
78 }
79
MakeSandboxJson(const char * sandboxFileName,const int MODE)80 cJSON *MakeSandboxJson(const char *sandboxFileName, const int MODE)
81 {
82 cJSON *mJsonSandbox = cJSON_CreateObject(); // json file object
83 cJSON *mJsonMtBdPth = cJSON_CreateArray(); // mount-bind-paths
84 cJSON *mJsonMtBdFl = cJSON_CreateArray(); // mount-bind-files
85 cJSON *mJsonSymLk = cJSON_CreateArray(); // symbol-links
86 cJSON *mJsonMtBdPthItmSdxFlg = cJSON_CreateArray(); // mount-bind-paths items sandbox-flags
87 cJSON *mJsonMtBdFlItm = cJSON_CreateObject(); // mount-bind-files items
88
89 if (mJsonSandbox == nullptr || mJsonMtBdPth == nullptr || mJsonMtBdFl == nullptr ||
90 mJsonSymLk == nullptr || mJsonMtBdPthItmSdxFlg == nullptr || mJsonMtBdFlItm == nullptr) {
91 std::cout << "create json object error" << std::endl;
92 return nullptr;
93 }
94 cJSON *mJsonMtBdPth_Itm; // point to mount-bind-paths items
95 cJSON *mJsonSymLk_Itm; // point to symbol-links items
96
97 // drop root path
98 if (MODE != NULL_ROOT_PATH) {
99 cJSON_AddItemToObject(mJsonSandbox, SANDBOX_CONFIG[0], cJSON_CreateString(SANDBOX_ROOT[0]));
100 }
101
102 // assemble SANDBOX_FLAGS
103 if (MODE != NULL_MOUNT_FLAGS) {
104 for (int i = 0; i < FLAGS_NUMBER; i++) {
105 cJSON_AddItemToArray(mJsonMtBdPthItmSdxFlg, cJSON_CreateString(SANDBOX_FLAGS[i]));
106 }
107 }
108
109 // assemble mount-bind-paths items
110 // Append items to mount-bind-paths
111 for (size_t i = 0; i < (sizeof(APP_PATHS) / sizeof(char *)); i++) {
112 cJSON_AddItemToArray(mJsonMtBdPth, mJsonMtBdPth_Itm = cJSON_CreateObject());
113 int MOUNT_FLAG_COUNT = 2;
114 if (MODE != NULL_MOUNT_ITEM) {
115 cJSON_AddItemToObject(mJsonMtBdPth_Itm, MOUNT_BIND_PATHS[0], cJSON_CreateString(APP_PATHS[i]));
116 cJSON_AddItemToObject(mJsonMtBdPth_Itm, MOUNT_BIND_PATHS[1], cJSON_CreateString(APP_PATHS[i]));
117 } else {
118 cJSON_AddItemToObject(mJsonMtBdPth_Itm, MOUNT_BIND_PATHS[0], nullptr);
119 cJSON_AddItemToObject(mJsonMtBdPth_Itm, MOUNT_BIND_PATHS[1], nullptr);
120 }
121 cJSON_AddItemToObject(mJsonMtBdPth_Itm, MOUNT_BIND_PATHS[MOUNT_FLAG_COUNT], mJsonMtBdPthItmSdxFlg);
122 }
123 if (MODE != NULL_MOUNT) {
124 cJSON_AddItemToObject(mJsonMtBdFlItm, SANDBOX_CONFIG[1], cJSON_CreateString("/data/init_ut/testsandboxfile"));
125 // Append items to mount-bind-files
126 cJSON_AddItemToArray(mJsonMtBdFl, mJsonMtBdFlItm);
127 // assemble symbol-links items
128 for (int i = LINK_ARRARY_START; i < LINK_ARRARY_END; i++) {
129 // Append items to symbol-links
130 cJSON_AddItemToArray(mJsonSymLk, mJsonSymLk_Itm = cJSON_CreateObject());
131 cJSON_AddItemToObject(mJsonSymLk_Itm, SYMBOL_LINKS[0], cJSON_CreateString(APP_PATHS[i]));
132 cJSON_AddItemToObject(mJsonSymLk_Itm, SYMBOL_LINKS[1], cJSON_CreateString(APP_PATHS[i]));
133 }
134 }
135
136 // at last, assemble the json file
137 int count = 1;
138 cJSON_AddItemToObject(mJsonSandbox, SANDBOX_CONFIG[count++], mJsonMtBdPth);
139 cJSON_AddItemToObject(mJsonSandbox, SANDBOX_CONFIG[count++], mJsonMtBdFl);
140 cJSON_AddItemToObject(mJsonSandbox, SANDBOX_CONFIG[count], mJsonSymLk);
141 return mJsonSandbox;
142 }
143
MakeFileByJson(cJSON * mJson,const char * sandboxFileName)144 bool MakeFileByJson(cJSON * mJson, const char *sandboxFileName)
145 {
146 const std::string sandboxJsonPth = std::string("/data/init_ut/") + std::string(sandboxFileName);
147 const char* cSandboxJsonPth = sandboxJsonPth.c_str();
148 int fd = open(cSandboxJsonPth, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0644);
149 if (fd < 0) {
150 std::cout << "open sandbox json file failed" << std::endl;
151 return false;
152 }
153
154 char *cjValue1 = cJSON_Print(mJson);
155 int ret1 = write(fd, cjValue1, strlen(cjValue1));
156 if (-1 == ret1) {
157 std::cout << "Write file ERROR" << errno << " fd is :" << fd << std::endl;
158 close(fd);
159 return false;
160 }
161 free(cjValue1);
162 close(fd);
163 return true;
164 }
165
166 class SandboxUnitTest : public testing::Test {
167 public:
SetUpTestCase(void)168 static void SetUpTestCase(void) {}
TearDownTestCase(void)169 static void TearDownTestCase(void) {}
SetUp()170 void SetUp() {};
TearDown()171 void TearDown() {};
172 };
173
174 HWTEST_F(SandboxUnitTest, TestCreateNormalSandbox, TestSize.Level1) {
175 cJSON *mJson = MakeSandboxJson(SANDBOX_JSON_NAME, 0);
176 if (mJson == nullptr) {
177 std::cout << "created mJson error, mJson is null." << std::endl;
178 return;
179 }
180 MakeFileByJson(mJson, SANDBOX_JSON_NAME);
181 int ret = RestartSandbox(TEST_SANDBOX_NAME);
182 ASSERT_EQ(ret, 0);
183 }
184
185 HWTEST_F(SandboxUnitTest, TestEnterErrorSandbox, TestSize.Level1) {
186 int ret1 = EnterSandbox("error_system");
187 ASSERT_EQ(ret1, -1);
188 const char *pname = nullptr;
189 int ret2 = EnterSandbox(pname);
190 ASSERT_EQ(ret2, -1);
191 DestroySandbox(TEST_SANDBOX_NAME);
192 int ret3 = EnterSandbox(TEST_SANDBOX_NAME);
193 ASSERT_EQ(ret3, -1);
194 }
195
196 HWTEST_F(SandboxUnitTest, TestCreateErrorSandbox1, TestSize.Level1) {
197 const char *pname = nullptr;
198 std::cout << "test destroy nullptr" << std::endl;
199 DestroySandbox(pname);
200 std::cout << "test destroy xapp" << std::endl;
201 DestroySandbox("xapp");
202 std::cout << "test enter xapp" << std::endl;
203 int ret1 = EnterSandbox("xapp");
204 ASSERT_EQ(ret1, -1);
205 bool result = InitSandboxWithName(pname);
206 ASSERT_FALSE(result);
207 DumpSandboxByName(pname);
208 DumpSandboxByName("xpp");
209 result = InitSandboxWithName("xapp");
210 ASSERT_FALSE(result);
211 }
212
213 HWTEST_F(SandboxUnitTest, TestCreateErrorSandbox2, TestSize.Level1) {
214 cJSON *mJson = MakeSandboxJson(SANDBOX_JSON_NAME, NULL_ROOT_PATH);
215 if (mJson == nullptr) {
216 std::cout << "created mJson error, mJson is null." << std::endl;
217 return;
218 }
219 bool ret1 = MakeFileByJson(mJson, SANDBOX_JSON_NAME);
220 ASSERT_TRUE(ret1);
221 InitSandboxWithName(TEST_SANDBOX_NAME);
222 int ret = PrepareSandbox(TEST_SANDBOX_NAME);
223 ASSERT_EQ(ret, -1);
224 ret = PrepareSandbox("xapp");
225 ASSERT_EQ(ret, -1);
226 }
227
228 HWTEST_F(SandboxUnitTest, TestCreateSandboxNoneJsonError, TestSize.Level1) {
229 unlink("/etc/sandbox/test-sandbox.json");
230 int ret = PrepareSandbox(TEST_SANDBOX_NAME);
231 ASSERT_EQ(ret, -1);
232 }
233
234 HWTEST_F(SandboxUnitTest, TestCreateSandboxMountFlagsError, TestSize.Level1) {
235 cJSON *mJson = MakeSandboxJson(SANDBOX_JSON_NAME, NULL_MOUNT_FLAGS);
236 if (mJson == nullptr) {
237 std::cout << "created mJson error, mJson is null." << std::endl;
238 return;
239 }
240 MakeFileByJson(mJson, SANDBOX_JSON_NAME);
241 int ret = PrepareSandbox(TEST_SANDBOX_NAME);
242 ASSERT_EQ(ret, -1);
243 }
244
245 HWTEST_F(SandboxUnitTest, TestCreateSandboxMountNULLError, TestSize.Level1) {
246 cJSON *mJson = MakeSandboxJson(SANDBOX_JSON_NAME, NULL_MOUNT_ITEM);
247 if (mJson == nullptr) {
248 std::cout << "created mJson error, mJson is null." << std::endl;
249 return;
250 }
251 MakeFileByJson(mJson, SANDBOX_JSON_NAME);
252 int ret = PrepareSandbox(TEST_SANDBOX_NAME);
253 ASSERT_EQ(ret, -1);
254 InitSandboxWithName(TEST_SANDBOX_NAME);
255 ASSERT_EQ(ret, -1);
256 }
257
258 HWTEST_F(SandboxUnitTest, TestUnshareNamespace, TestSize.Level1) {
259 int ret1 = UnshareNamespace(-1);
260 ASSERT_EQ(ret1, -1);
261 }
262
263 HWTEST_F(SandboxUnitTest, TestSetNamespace, TestSize.Level1) {
264 int ret1 = SetNamespace(-1, 1);
265 ASSERT_EQ(ret1, -1);
266 ret1 = SetNamespace(1, -1);
267 ASSERT_EQ(ret1, -1);
268 }
269
270 HWTEST_F(SandboxUnitTest, TestGetNamespaceFd, TestSize.Level1) {
271 int ret1 = GetNamespaceFd("");
272 GetNamespaceFd(nullptr);
273 ASSERT_EQ(ret1, -1);
274 const std::string sandboxJsonPth = std::string("/mnt/sandbox/") + std::string(TEST_SANDBOX_NAME);
275 const char* cSandboxJsonPth = sandboxJsonPth.c_str();
276 ret1 = GetNamespaceFd(cSandboxJsonPth);
277 EXPECT_GT(ret1, 1);
278 }
279 }
280