1 /*
2 * Copyright (c) 2022-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 "unit_test.h"
17 #include <string>
18 #include <thread>
19 #include <selinux/selinux.h>
20 #include "selinux_error.h"
21 #include "test_common.h"
22
23 namespace OHOS {
24 namespace Security {
25 namespace SelinuxUnitTest {
26 using namespace testing::ext;
27 using namespace Selinux;
28 const static int SLEEP_SECOND = 2;
29 const static std::string BASE_PATH = "/data/app/el1/0/base/";
30 const static std::string ACCOUNT_PATH = "/data/accounts/account_0/appdata/";
31 const static std::string TEST_HAP_PATH = BASE_PATH + "com.ohos.selftest/";
32 const static std::string TEST_ACCOUNT_PATH = ACCOUNT_PATH + "com.ohos.selftest/";
33 const static std::string TEST_ACCOUNT_SUB_PATH_1_FILE_1 = TEST_ACCOUNT_PATH + "file1.txt";
34
35 const static std::string TEST_SUB_PATH_1 = TEST_HAP_PATH + "subpath1/";
36 const static std::string TEST_SUB_PATH_2 = TEST_HAP_PATH + "subpath2/";
37 const static std::string TEST_SUB_PATH_3 = TEST_HAP_PATH + "subpath3/";
38 const static std::string TEST_SUB_PATH_4 = TEST_HAP_PATH + "subpath4/";
39
40 const static std::string TEST_SUB_PATH_1_FILE_1 = TEST_SUB_PATH_1 + "file1.txt";
41 const static std::string TEST_SUB_PATH_1_FILE_2 = TEST_SUB_PATH_1 + "file2.txt";
42 const static std::string TEST_SUB_PATH_2_FILE_1 = TEST_SUB_PATH_2 + "file1.txt";
43 const static std::string TEST_SUB_PATH_2_FILE_2 = TEST_SUB_PATH_2 + "file2.txt";
44 const static std::string TEST_SUB_PATH_3_FILE_1 = TEST_SUB_PATH_3 + "file1.txt";
45 const static std::string TEST_SUB_PATH_3_FILE_2 = TEST_SUB_PATH_3 + "file2.txt";
46 const static std::string TEST_SUB_PATH_4_FILE_1 = TEST_SUB_PATH_4 + "file1.txt";
47 const static std::string TEST_SUB_PATH_4_FILE_2 = TEST_SUB_PATH_4 + "file2.txt";
48
49 const static std::string TEST_UNSIMPLIFY_PATH = TEST_SUB_PATH_3 + "//../subpath4/";
50 const static std::string TEST_UNSIMPLIFY_FILE = TEST_SUB_PATH_4 + "//../subpath3/file1.txt";
51
52 const static std::string INVALID_PATH = "/data/data/path";
53 const static std::string EMPTY_STRING = "";
54 const static std::string SYSTEM_CORE_APL = "system_core";
55 const static std::string NORMAL_APL = "normal";
56 const static std::string INVALID_APL = "invalid_apl";
57
58 const static std::string TEST_HAP_BUNDLE_NAME = "com.hap.selftest";
59 const static std::string TEST_HAP_BUNDLE_NAME_WITH_NO_CONTEXTS = "com.ohos.test";
60 const static std::string TEST_HAP_BUNDLE_NAME_FOR_INVALID_CONTEXTS = "com.hap.selftest_invalid";
61
62 const static std::string TEST_HAP_DATA_FILE_LABEL = "u:object_r:selftest_hap_data_file:s0";
63
64 const static std::string TEST_HAP_DOMAIN = "u:r:selftest:s0";
65 const static std::string TEST_HAP_DATA_TYPE = "u:r:selftest_hap_data_file:s0";
66 const static std::string DLP_HAP_DOMAIN = "u:r:dlp_sandbox_hap:s0";
67 const static std::string DLP_HAP_DATA_TYPE = "u:r:dlp_sandbox_hap_data_file:s0";
68 const static std::string TEST_NORMAL_DOMAIN = "u:r:normal_hap:s0";
69 const static std::string TEST_NOMAL_TYPE = "u:r:normal_hap_data_file:s0";
70 const static std::string TEST_EXTENSION_DOMAIN = "u:r:extension_test_hap:s0";
71 const static std::string TEST_EXTENSION_SAME_DOMAIN = "u:r:extension_test_same_hap:s0";
72 const static std::string TEST_EXTENSION_DEBUG_DOMAIN = "u:r:extension_test_debug_hap:s0";
73 const static std::string TEST_EXTENSION_PREINSTALL_DOMAIN = "u:r:extension_test_preinstall_hap:s0";
74 const static std::string TEST_EXTENSION = "extension_test_ability";
75 const static std::string TEST_SAME_EXTENSION = "extension_same_ability";
76 const static std::string TEST_DEBUG_EXTENSION = "extension_test_debug_ability";
77 const static std::string TEST_NORMAL_DOMAIN_WITH_CATEGORY = "o:r:normal_hap:s0:x214,x486,x514,x868,x1024";
78 const static uint32_t TEST_UID = 20190166;
79
80 const static std::string SEHAP_CONTEXTS_FILE = "/data/test/sehap_contexts";
81
82 static HapFileInfo g_hapFileInfoWithoutFlags = {
83 .pathNameOrig = {TEST_SUB_PATH_1},
84 .apl = SYSTEM_CORE_APL,
85 .packageName = TEST_HAP_BUNDLE_NAME,
86 .flags = 0,
87 .hapFlags = 1,
88 };
89
90 static HapFileInfo g_hapFileInfoWithFlags = {
91 .pathNameOrig = {TEST_HAP_PATH},
92 .apl = SYSTEM_CORE_APL,
93 .packageName = TEST_HAP_BUNDLE_NAME,
94 .flags = 1,
95 .hapFlags = 1,
96 };
97
98 static HapFileInfo g_hapFileInfoWithAplEmpty = {
99 .pathNameOrig = {TEST_HAP_PATH},
100 .apl = "",
101 .packageName = TEST_HAP_BUNDLE_NAME,
102 .flags = 0,
103 .hapFlags = 1,
104 };
105
106 static HapFileInfo g_hapFileInfoWithPathEmpty = {
107 .pathNameOrig = {},
108 .apl = SYSTEM_CORE_APL,
109 .packageName = TEST_HAP_BUNDLE_NAME,
110 .flags = 0,
111 .hapFlags = 1,
112 };
113
114 static HapFileInfo g_hapFileInfoWithAplInvalid = {
115 .pathNameOrig = {TEST_HAP_PATH},
116 .apl = INVALID_APL,
117 .packageName = TEST_HAP_BUNDLE_NAME,
118 .flags = 0,
119 .hapFlags = 1,
120 };
121
122 static HapFileInfo g_hapFileInfoWithCannotFindContexts = {
123 .pathNameOrig = {TEST_HAP_PATH},
124 .apl = SYSTEM_CORE_APL,
125 .packageName = TEST_HAP_BUNDLE_NAME_WITH_NO_CONTEXTS,
126 .flags = 0,
127 .hapFlags = 1,
128 };
129
130 static HapFileInfo g_hapFileInfoForRepeatLabel = {
131 .pathNameOrig = {TEST_SUB_PATH_1},
132 .apl = SYSTEM_CORE_APL,
133 .packageName = TEST_HAP_BUNDLE_NAME,
134 .flags = 0,
135 .hapFlags = 1,
136 };
137
138 static HapFileInfo g_hapFileInfoWithPreinstallHap = {
139 .pathNameOrig = {TEST_SUB_PATH_1},
140 .apl = SYSTEM_CORE_APL,
141 .packageName = TEST_HAP_BUNDLE_NAME,
142 .flags = 0,
143 .hapFlags = 0,
144 };
145
146 static HapFileInfo g_hapFileInfoWithInvalidPath = {
147 .pathNameOrig = {TEST_SUB_PATH_1, INVALID_PATH},
148 .apl = SYSTEM_CORE_APL,
149 .packageName = TEST_HAP_BUNDLE_NAME,
150 .flags = 0,
151 .hapFlags = 1,
152 };
153
154 static HapFileInfo g_hapFileInfoForInvalidContexts = {
155 .pathNameOrig = {TEST_HAP_PATH},
156 .apl = NORMAL_APL,
157 .packageName = TEST_HAP_BUNDLE_NAME_FOR_INVALID_CONTEXTS,
158 .flags = 0,
159 .hapFlags = 1,
160 };
161
162 static HapDomainInfo g_hapDomainInfoWithAplEmpty {
163 .apl = "",
164 .packageName = TEST_HAP_BUNDLE_NAME,
165 .hapFlags = 1,
166 };
167
168 static HapDomainInfo g_hapDomainInfoWithInvalidApl {
169 .apl = INVALID_APL,
170 .packageName = TEST_HAP_BUNDLE_NAME,
171 .hapFlags = 1,
172 };
173
174 static HapDomainInfo g_hapDomainInfo {
175 .apl = SYSTEM_CORE_APL,
176 .packageName = TEST_HAP_BUNDLE_NAME,
177 .hapFlags = 1,
178 };
179
180 static HapDomainInfo g_hapDomainInfoForInvalidContexts {
181 .apl = NORMAL_APL,
182 .packageName = TEST_HAP_BUNDLE_NAME_FOR_INVALID_CONTEXTS,
183 .hapFlags = 1,
184 };
185
GenerateTestFile()186 static void GenerateTestFile()
187 {
188 std::vector<std::string> sehapInfo = {
189 "apl=system_core domain=system_core_hap type=system_core_hap_data_file",
190 "apl=system_basic domain=system_basic_hap type=system_basic_hap_data_file",
191 "apl=normal domain=normal_hap type=normal_hap_data_file",
192 "apl=normal debuggable=true domain=debug_hap type=debug_hap_data_file",
193 "apl=system_core name=com.ohos.test domain= type=",
194 "apl=system_core domain=selftest type=selftest_hap_data_file",
195 "apl=system_core name=com.hap.selftest domain=selftest type=selftest_hap_data_file",
196 "apl=normal name=com.hap.selftest domain=selftest type=normal_hap_data_file",
197 "apl=normal name=com.hap.selftest_invalid domain=selftest_invalid type=selftest_invalid_hap_data_file",
198 "apl=normal extra=invalid_extra domain=dlp_sandbox_hap type=dlp_sandbox_hap_data_file",
199 "apl=normal extra=dlp_sandbox domain=dlp_sandbox_hap type=dlp_sandbox_hap_data_file",
200 "apl=normal domain=extension_test_hap extension=extension_test_ability",
201 "apl=normal domain=extension_test_same_hap extension=extension_same_ability",
202 "apl=normal debuggable=true domain=extension_test_debug_hap extension=extension_test_debug_ability",
203 "apl=normal name=com.hap.selftest domain=extension_test_preinstall_hap extension=extension_test_ability"};
204 ASSERT_EQ(true, WriteFile(SEHAP_CONTEXTS_FILE, sehapInfo));
205 }
206
RemoveTestFile()207 static void RemoveTestFile()
208 {
209 unlink(SEHAP_CONTEXTS_FILE.c_str());
210 }
211
SetUpTestCase()212 void SelinuxUnitTest::SetUpTestCase()
213 {
214 // make test case clean
215 GenerateTestFile();
216 }
217
TearDownTestCase()218 void SelinuxUnitTest::TearDownTestCase()
219 {
220 RemoveTestFile();
221 }
222
SetUp()223 void SelinuxUnitTest::SetUp() {}
224
TearDown()225 void SelinuxUnitTest::TearDown() {}
226
CreateDataFile() const227 void SelinuxUnitTest::CreateDataFile() const {}
228
229 /**
230 * @tc.name: HapFileRestorecon001
231 * @tc.desc: test HapFileRestorecon input para invalid.
232 * @tc.type: FUNC
233 * @tc.require: AR000GJSDQ
234 */
235 HWTEST_F(SelinuxUnitTest, HapFileRestorecon001, TestSize.Level1)
236 {
237 ASSERT_EQ(true, CreateDirectory(TEST_HAP_PATH));
238
239 EXPECT_EQ(-SELINUX_ARG_INVALID, test.HapFileRestorecon(g_hapFileInfoWithAplEmpty));
240
241 EXPECT_EQ(-SELINUX_ARG_INVALID, test.HapFileRestorecon(g_hapFileInfoWithPathEmpty));
242
243 EXPECT_EQ(-SELINUX_ARG_INVALID, test.HapFileRestorecon(g_hapFileInfoWithAplInvalid));
244
245 ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
246 }
247
248 /**
249 * @tc.name: HapFileRestorecon002
250 * @tc.desc: test HapFileRestorecon normal branch without restorecon.
251 * @tc.type: FUNC
252 * @tc.require:AR000GJSDQ
253 */
254 HWTEST_F(SelinuxUnitTest, HapFileRestorecon002, TestSize.Level1)
255 {
256 ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_1_FILE_1)); // this file should not be restorecon
257
258 char *secontextOld = nullptr;
259 getfilecon(TEST_SUB_PATH_1_FILE_1.c_str(), &secontextOld);
260
261 int ret = test.HapFileRestorecon(g_hapFileInfoWithoutFlags);
262 ASSERT_EQ(SELINUX_SUCC, ret);
263
264 char *secontextNew = nullptr;
265 getfilecon(TEST_SUB_PATH_1.c_str(), &secontextNew);
266 EXPECT_STREQ(TEST_HAP_DATA_FILE_LABEL.c_str(), secontextNew);
267 freecon(secontextNew);
268 secontextNew = nullptr;
269
270 getfilecon(TEST_SUB_PATH_1_FILE_1.c_str(), &secontextNew);
271 EXPECT_STREQ(secontextOld, secontextNew);
272 freecon(secontextNew);
273 secontextNew = nullptr;
274
275 ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
276 }
277
278 /**
279 * @tc.name: HapFileRestorecon003
280 * @tc.desc: test HapFileRestorecon normal branch with restorecon.
281 * @tc.type: FUNC
282 * @tc.require:AR000GJSDQ
283 */
284 HWTEST_F(SelinuxUnitTest, HapFileRestorecon003, TestSize.Level1)
285 {
286 ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_1_FILE_1));
287 ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_1_FILE_2));
288 ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_2_FILE_1));
289 ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_2_FILE_2));
290
291 int ret = test.HapFileRestorecon(g_hapFileInfoWithFlags);
292 ASSERT_EQ(SELINUX_SUCC, ret);
293
294 char *secontext = nullptr;
295 getfilecon(TEST_SUB_PATH_1.c_str(), &secontext);
296 EXPECT_STREQ(TEST_HAP_DATA_FILE_LABEL.c_str(), secontext);
297 freecon(secontext);
298 secontext = nullptr;
299
300 getfilecon(TEST_SUB_PATH_2.c_str(), &secontext);
301 EXPECT_STREQ(TEST_HAP_DATA_FILE_LABEL.c_str(), secontext);
302 freecon(secontext);
303 secontext = nullptr;
304
305 getfilecon(TEST_SUB_PATH_1_FILE_1.c_str(), &secontext);
306 EXPECT_STREQ(TEST_HAP_DATA_FILE_LABEL.c_str(), secontext);
307 freecon(secontext);
308 secontext = nullptr;
309
310 getfilecon(TEST_SUB_PATH_1_FILE_2.c_str(), &secontext);
311 EXPECT_STREQ(TEST_HAP_DATA_FILE_LABEL.c_str(), secontext);
312 freecon(secontext);
313 secontext = nullptr;
314
315 getfilecon(TEST_SUB_PATH_2_FILE_1.c_str(), &secontext);
316 EXPECT_STREQ(TEST_HAP_DATA_FILE_LABEL.c_str(), secontext);
317 freecon(secontext);
318 secontext = nullptr;
319
320 getfilecon(TEST_SUB_PATH_2_FILE_2.c_str(), &secontext);
321 EXPECT_STREQ(TEST_HAP_DATA_FILE_LABEL.c_str(), secontext);
322 freecon(secontext);
323 secontext = nullptr;
324
325 ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
326 }
327
328 /**
329 * @tc.name: HapFileRestorecon004
330 * @tc.desc: test HapFileRestorecon with single path input para invalid.
331 * @tc.type: FUNC
332 * @tc.require: AR000GJSDQ
333 */
334 HWTEST_F(SelinuxUnitTest, HapFileRestorecon004, TestSize.Level1)
335 {
336 ASSERT_EQ(true, CreateDirectory(TEST_HAP_PATH));
337
338 EXPECT_EQ(-SELINUX_ARG_INVALID, test.HapFileRestorecon(TEST_HAP_PATH, g_hapFileInfoWithAplEmpty));
339
340 EXPECT_EQ(-SELINUX_ARG_INVALID, test.HapFileRestorecon(EMPTY_STRING, g_hapFileInfoWithPathEmpty));
341
342 EXPECT_EQ(-SELINUX_ARG_INVALID, test.HapFileRestorecon(TEST_HAP_PATH, g_hapFileInfoWithAplInvalid));
343
344 EXPECT_EQ(-SELINUX_CHECK_CONTEXT_ERROR, test.HapFileRestorecon(TEST_HAP_PATH, g_hapFileInfoForInvalidContexts));
345
346 ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
347 }
348
349 /**
350 * @tc.name: HapFileRestorecon005
351 * @tc.desc: test HapFileRestorecon with no recurce.
352 * @tc.type: FUNC
353 * @tc.require: AR000GJSDQ
354 */
355 HWTEST_F(SelinuxUnitTest, HapFileRestorecon005, TestSize.Level1)
356 {
357 ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_1_FILE_1));
358
359 EXPECT_EQ(SELINUX_SUCC, test.HapFileRestorecon(TEST_HAP_PATH, g_hapFileInfoWithoutFlags));
360
361 ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
362 }
363
364 /**
365 * @tc.name: HapFileRestorecon006
366 * @tc.desc: test HapFileRestorecon checkPath fail.
367 * @tc.type: FUNC
368 * @tc.require: AR000GJSDQ
369 */
370 HWTEST_F(SelinuxUnitTest, HapFileRestorecon006, TestSize.Level1)
371 {
372 ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_1_FILE_1));
373
374 EXPECT_EQ(-SELINUX_PATH_INVALID, test.HapFileRestorecon(INVALID_PATH, g_hapFileInfoWithoutFlags));
375
376 ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
377 }
378
379 /**
380 * @tc.name: HapFileRestorecon007
381 * @tc.desc: test HapFileRestorecon with accounts path.
382 * @tc.type: FUNC
383 * @tc.require: AR000GJSDQ
384 */
385 HWTEST_F(SelinuxUnitTest, HapFileRestorecon007, TestSize.Level1)
386 {
387 ASSERT_EQ(true, CreateFile(TEST_ACCOUNT_SUB_PATH_1_FILE_1));
388
389 EXPECT_EQ(SELINUX_SUCC, test.HapFileRestorecon(TEST_ACCOUNT_SUB_PATH_1_FILE_1, g_hapFileInfoWithoutFlags));
390
391 ASSERT_EQ(true, RemoveDirectory(ACCOUNT_PATH));
392 }
393
394 /**
395 * @tc.name: HapFileRestorecon008
396 * @tc.desc: test HapFileRestorecon type is empty.
397 * @tc.type: FUNC
398 * @tc.require: AR000GJSDQ
399 */
400 HWTEST_F(SelinuxUnitTest, HapFileRestorecon008, TestSize.Level1)
401 {
402 ASSERT_EQ(true, CreateDirectory(TEST_HAP_PATH));
403
404 EXPECT_EQ(-SELINUX_KEY_NOT_FOUND, test.HapFileRestorecon(TEST_HAP_PATH, g_hapFileInfoWithCannotFindContexts));
405
406 ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
407 }
408
CompareContexts(const std::string & path,const std::string & label)409 static bool CompareContexts(const std::string &path, const std::string &label)
410 {
411 char *secontext = nullptr;
412 getfilecon(path.c_str(), &secontext);
413 bool res = (strcmp(label.c_str(), secontext) == 0);
414 freecon(secontext);
415 secontext = nullptr;
416 return res;
417 }
418
419 /**
420 * @tc.name: HapFileRestorecon009
421 * @tc.desc: test HapFileRestorecon input multi path/file no recurse.
422 * @tc.type: FUNC
423 * @tc.require:AR000GJSDQ
424 */
425 HWTEST_F(SelinuxUnitTest, HapFileRestorecon009, TestSize.Level1)
426 {
427 ASSERT_EQ(true, CreateDirectory(TEST_SUB_PATH_4));
428 ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_1_FILE_1));
429 ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_1_FILE_2));
430 ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_2_FILE_1)); // should not be restorecon
431 ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_3_FILE_1));
432
433 char *secontextOld = nullptr;
434 getfilecon(TEST_SUB_PATH_2_FILE_1.c_str(), &secontextOld);
435
436 HapFileInfo hapFileInfo = {
437 .pathNameOrig = {TEST_SUB_PATH_1, TEST_SUB_PATH_2, TEST_SUB_PATH_1_FILE_1, TEST_SUB_PATH_1_FILE_2,
438 TEST_UNSIMPLIFY_FILE, TEST_UNSIMPLIFY_PATH},
439 .apl = SYSTEM_CORE_APL,
440 .packageName = TEST_HAP_BUNDLE_NAME,
441 .flags = 0,
442 .hapFlags = 1,
443 };
444
445 ASSERT_EQ(SELINUX_SUCC, test.HapFileRestorecon(hapFileInfo));
446 EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_1, TEST_HAP_DATA_FILE_LABEL));
447 EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_2, TEST_HAP_DATA_FILE_LABEL));
448 EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_1_FILE_1, TEST_HAP_DATA_FILE_LABEL));
449 EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_1_FILE_2, TEST_HAP_DATA_FILE_LABEL));
450 EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_3_FILE_1, TEST_HAP_DATA_FILE_LABEL));
451 EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_4, TEST_HAP_DATA_FILE_LABEL));
452
453 char *secontext = nullptr;
454 getfilecon(TEST_SUB_PATH_2_FILE_1.c_str(), &secontext); // this file should not be restorecon
455 EXPECT_STREQ(secontextOld, secontext);
456 freecon(secontext);
457 freecon(secontextOld);
458 secontext = nullptr;
459 secontextOld = nullptr;
460
461 ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
462 }
463
464 /**
465 * @tc.name: HapFileRestorecon010
466 * @tc.desc: test HapFileRestorecon input multi path/file recurse.
467 * @tc.type: FUNC
468 * @tc.require:AR000GJSDQ
469 */
470 HWTEST_F(SelinuxUnitTest, HapFileRestorecon010, TestSize.Level1)
471 {
472 ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_1_FILE_1));
473 ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_1_FILE_2));
474 ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_2_FILE_1));
475 ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_2_FILE_2));
476 ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_3_FILE_1));
477 ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_3_FILE_2)); // this file should not be restorecon
478 ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_4_FILE_1));
479 ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_4_FILE_2));
480
481 char *secontextOld = nullptr;
482 getfilecon(TEST_SUB_PATH_3_FILE_2.c_str(), &secontextOld);
483
484 HapFileInfo hapFileInfo = {
485 .pathNameOrig = { TEST_SUB_PATH_1, TEST_SUB_PATH_2, TEST_UNSIMPLIFY_FILE, TEST_UNSIMPLIFY_PATH },
486 .apl = SYSTEM_CORE_APL,
487 .packageName = TEST_HAP_BUNDLE_NAME,
488 .flags = 1,
489 .hapFlags = 1,
490 };
491 ASSERT_EQ(SELINUX_SUCC, test.HapFileRestorecon(hapFileInfo));
492 EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_1, TEST_HAP_DATA_FILE_LABEL));
493 EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_2, TEST_HAP_DATA_FILE_LABEL));
494 EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_4, TEST_HAP_DATA_FILE_LABEL));
495 EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_1_FILE_1, TEST_HAP_DATA_FILE_LABEL));
496 EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_1_FILE_2, TEST_HAP_DATA_FILE_LABEL));
497 EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_2_FILE_1, TEST_HAP_DATA_FILE_LABEL));
498 EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_2_FILE_2, TEST_HAP_DATA_FILE_LABEL));
499 EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_4_FILE_1, TEST_HAP_DATA_FILE_LABEL));
500 EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_4_FILE_2, TEST_HAP_DATA_FILE_LABEL));
501 EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_3_FILE_1, TEST_HAP_DATA_FILE_LABEL));
502
503 char *secontext = nullptr;
504 getfilecon(TEST_SUB_PATH_3_FILE_2.c_str(), &secontext);
505 EXPECT_STREQ(secontextOld, secontext);
506 freecon(secontext);
507 freecon(secontextOld);
508 secontext = nullptr;
509 secontextOld = nullptr;
510
511 ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
512 }
513
514 /**
515 * @tc.name: HapFileRestorecon011
516 * @tc.desc: test HapFileRestorecon repeat label.
517 * @tc.type: FUNC
518 * @tc.require:AR000GJSDQ
519 */
520 HWTEST_F(SelinuxUnitTest, HapFileRestorecon011, TestSize.Level1)
521 {
522 ASSERT_EQ(true, CreateDirectory(TEST_SUB_PATH_1));
523 int ret = test.HapFileRestorecon(g_hapFileInfoForRepeatLabel);
524 ASSERT_EQ(SELINUX_SUCC, ret);
525
526 char *secontext = nullptr;
527 getfilecon(TEST_SUB_PATH_1.c_str(), &secontext);
528 EXPECT_STREQ(TEST_HAP_DATA_FILE_LABEL.c_str(), secontext);
529 freecon(secontext);
530 secontext = nullptr;
531
532 char *secontextOld = nullptr;
533 getfilecon(TEST_SUB_PATH_1.c_str(), &secontextOld);
534
535 ret = test.HapFileRestorecon(g_hapFileInfoForRepeatLabel); // double restorcon
536 ASSERT_EQ(SELINUX_SUCC, ret);
537
538 getfilecon(TEST_SUB_PATH_1.c_str(), &secontext);
539 EXPECT_STREQ(secontextOld, secontext);
540 freecon(secontext);
541 freecon(secontextOld);
542 secontext = nullptr;
543 secontextOld = nullptr;
544
545 ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
546 }
547
548 /**
549 * @tc.name: HapFileRestorecon012
550 * @tc.desc: test HapFileRestorecon normal branch with preinstalled app.
551 * @tc.type: FUNC
552 * @tc.require:AR000GJSDQ
553 */
554 HWTEST_F(SelinuxUnitTest, HapFileRestorecon012, TestSize.Level1)
555 {
556 ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_1_FILE_1));
557
558 int ret = test.HapFileRestorecon(g_hapFileInfoWithPreinstallHap);
559 ASSERT_EQ(SELINUX_SUCC, ret);
560
561 char *secontextNew = nullptr;
562 getfilecon(TEST_SUB_PATH_1.c_str(), &secontextNew);
563 EXPECT_STREQ(TEST_HAP_DATA_FILE_LABEL.c_str(), secontextNew);
564 freecon(secontextNew);
565 secontextNew = nullptr;
566
567 ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
568 }
569
570 /**
571 * @tc.name: HapFileRestorecon013
572 * @tc.desc: test HapFileRestorecon with multi path failed.
573 * @tc.type: FUNC
574 * @tc.require:
575 */
576 HWTEST_F(SelinuxUnitTest, HapFileRestorecon013, TestSize.Level1)
577 {
578 ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_1_FILE_1));
579 ASSERT_EQ(true, CreateFile(INVALID_PATH));
580
581 ASSERT_EQ(-SELINUX_RESTORECON_ERROR, test.HapFileRestorecon(g_hapFileInfoWithInvalidPath));
582
583 ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
584 ASSERT_EQ(true, RemoveDirectory(INVALID_PATH));
585 }
586
587 /**
588 * @tc.name: HapFileRecurseRestorecon001
589 * @tc.desc: test HapFileRecurseRestorecon realPath is nullptr.
590 * @tc.type: FUNC
591 * @tc.require: AR000GJSDQ
592 */
593 HWTEST_F(SelinuxUnitTest, HapFileRecurseRestorecon001, TestSize.Level1)
594 {
595 int ret = test.HapFileRecurseRestorecon(nullptr, g_hapFileInfoWithCannotFindContexts);
596 ASSERT_EQ(-SELINUX_FTS_OPEN_ERROR, ret);
597 }
598
599 /**
600 * @tc.name: RestoreconSb001
601 * @tc.desc: test RestoreconSb with repeat label.
602 * @tc.type: FUNC
603 * @tc.require: AR000GJSDQ
604 */
605 HWTEST_F(SelinuxUnitTest, RestoreconSb001, TestSize.Level1)
606 {
607 ASSERT_EQ(true, CreateDirectory(TEST_SUB_PATH_1));
608
609 ASSERT_EQ(SELINUX_SUCC, test.RestoreconSb(TEST_SUB_PATH_1, g_hapFileInfoForRepeatLabel));
610 char *secontextOld = nullptr;
611 getfilecon(TEST_SUB_PATH_1.c_str(), &secontextOld);
612 EXPECT_STREQ(secontextOld, TEST_HAP_DATA_FILE_LABEL.c_str());
613 freecon(secontextOld);
614
615 ASSERT_EQ(SELINUX_SUCC, test.RestoreconSb(TEST_SUB_PATH_1, g_hapFileInfoForRepeatLabel)); // double restorcon
616 char *secontextNew = nullptr;
617 getfilecon(TEST_SUB_PATH_1.c_str(), &secontextNew);
618 EXPECT_STREQ(secontextNew, TEST_HAP_DATA_FILE_LABEL.c_str());
619 freecon(secontextNew);
620
621 ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
622 }
623
624 /**
625 * @tc.name: HapDomainSetcontext001
626 * @tc.desc: test HapDomainSetcontext input para invalid.
627 * @tc.type: FUNC
628 * @tc.require: issueI6JV34
629 */
630 HWTEST_F(SelinuxUnitTest, HapDomainSetcontext001, TestSize.Level1)
631 {
632 ASSERT_EQ(true, CreateDirectory(TEST_HAP_PATH));
633
634 EXPECT_EQ(-SELINUX_ARG_INVALID, test.HapDomainSetcontext(g_hapDomainInfoWithAplEmpty));
635 EXPECT_EQ(-SELINUX_ARG_INVALID, test.HapDomainSetcontext(g_hapDomainInfoWithInvalidApl));
636
637 ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
638 }
639
640 /**
641 * @tc.name: HapDomainSetcontext002
642 * @tc.desc: test HapDomainSetcontext must succeed
643 * @tc.type: FUNC
644 * @tc.require: issueI6JV34
645 */
646 HWTEST_F(SelinuxUnitTest, HapDomainSetcontext002, TestSize.Level1)
647 {
648 pid_t pid = fork();
649 ASSERT_TRUE(pid >= 0);
650 if (pid == 0) {
651 EXPECT_EQ(SELINUX_SUCC, test.HapDomainSetcontext(g_hapDomainInfo));
652 usleep(200000); // sleep 200ms
653 exit(0);
654 } else {
655 usleep(150000); // sleep 150ms
656 char *con = nullptr;
657 ASSERT_EQ(0, getpidcon(pid, &con));
658 EXPECT_STREQ(con, TEST_HAP_DOMAIN.c_str());
659 freecon(con);
660 }
661 }
662
663 /**
664 * @tc.name: HapDomainSetcontext003
665 * @tc.desc: test HapDomainSetcontext setcon normal_hap.
666 * @tc.type: FUNC
667 * @tc.require: issueI6JV34
668 */
669 HWTEST_F(SelinuxUnitTest, HapDomainSetcontext003, TestSize.Level1)
670 {
671 pid_t pid = fork();
672 ASSERT_TRUE(pid >= 0);
673 if (pid == 0) {
674 EXPECT_EQ(-SELINUX_CHECK_CONTEXT_ERROR, test.HapDomainSetcontext(g_hapDomainInfoForInvalidContexts));
675 exit(0);
676 }
677 }
678
679 /**
680 * @tc.name: HapContextsLookup001
681 * @tc.desc: test HapContextsLookup must succeed
682 * @tc.type: FUNC
683 * @tc.require: issueI9MCSP
684 */
685 HWTEST_F(SelinuxUnitTest, HapContextsLookup001, TestSize.Level1)
686 {
687 char *oldTypeContext = nullptr;
688 ASSERT_EQ(SELINUX_SUCC, getcon(&oldTypeContext));
689 context_t con = context_new(oldTypeContext);
690
691 HapContextParams params;
692 params.apl = SYSTEM_CORE_APL;
693 params.packageName = EMPTY_STRING;
694 params.hapFlags = 0;
695 EXPECT_EQ(SELINUX_SUCC, test.HapContextsLookup(params, true, con));
696 EXPECT_STREQ(context_str(con), TEST_HAP_DOMAIN.c_str());
697
698 params.apl = NORMAL_APL;
699 params.packageName = EMPTY_STRING;
700 params.hapFlags = 0;
701 EXPECT_EQ(SELINUX_SUCC, test.HapContextsLookup(params, true, con));
702 EXPECT_STREQ(context_str(con), TEST_NORMAL_DOMAIN.c_str());
703
704 params.apl = NORMAL_APL;
705 params.packageName = TEST_HAP_BUNDLE_NAME;
706 params.hapFlags = SELINUX_HAP_RESTORECON_PREINSTALLED_APP;
707 EXPECT_EQ(SELINUX_SUCC, test.HapContextsLookup(params, true, con));
708 EXPECT_STREQ(context_str(con), TEST_HAP_DOMAIN.c_str());
709
710 params.apl = NORMAL_APL;
711 params.packageName = EMPTY_STRING;
712 params.hapFlags = SELINUX_HAP_DLP;
713 EXPECT_EQ(SELINUX_SUCC, test.HapContextsLookup(params, true, con));
714 EXPECT_STREQ(context_str(con), DLP_HAP_DOMAIN.c_str());
715
716 params.apl = NORMAL_APL;
717 params.packageName = EMPTY_STRING;
718 params.hapFlags = SELINUX_HAP_DLP | SELINUX_HAP_DEBUGGABLE;
719 EXPECT_EQ(SELINUX_SUCC, test.HapContextsLookup(params, true, con));
720 EXPECT_STREQ(context_str(con), DLP_HAP_DOMAIN.c_str());
721
722 params.apl = NORMAL_APL;
723 params.packageName = EMPTY_STRING;
724 params.hapFlags = 0;
725 EXPECT_EQ(SELINUX_SUCC, test.HapContextsLookup(params, con, TEST_UID));
726 EXPECT_STREQ(context_str(con), TEST_NORMAL_DOMAIN_WITH_CATEGORY.c_str());
727
728 freecon(oldTypeContext);
729 context_free(con);
730 }
731
732 /**
733 * @tc.name: HapContextsLookup002
734 * @tc.desc: test HapContextsLookup must succeed
735 * @tc.type: FUNC
736 * @tc.require: issueI9MCSP
737 */
738 HWTEST_F(SelinuxUnitTest, HapContextsLookup002, TestSize.Level1)
739 {
740 char *oldTypeContext = nullptr;
741 ASSERT_EQ(SELINUX_SUCC, getcon(&oldTypeContext));
742 context_t con = context_new(oldTypeContext);
743
744 HapContextParams params;
745 params.apl = SYSTEM_CORE_APL;
746 params.packageName = EMPTY_STRING;
747 params.hapFlags = 0;
748 EXPECT_EQ(SELINUX_SUCC, test.HapContextsLookup(params, false, con));
749 EXPECT_STREQ(context_str(con), TEST_HAP_DATA_TYPE.c_str());
750
751 params.apl = NORMAL_APL;
752 params.packageName = EMPTY_STRING;
753 params.hapFlags = 0;
754 EXPECT_EQ(SELINUX_SUCC, test.HapContextsLookup(params, false, con));
755 EXPECT_STREQ(context_str(con), TEST_NOMAL_TYPE.c_str());
756
757 params.apl = NORMAL_APL;
758 params.packageName = TEST_HAP_BUNDLE_NAME;
759 params.hapFlags = SELINUX_HAP_RESTORECON_PREINSTALLED_APP;
760 EXPECT_EQ(SELINUX_SUCC, test.HapContextsLookup(params, false, con));
761 EXPECT_STREQ(context_str(con), TEST_NOMAL_TYPE.c_str());
762
763 params.apl = NORMAL_APL;
764 params.packageName = EMPTY_STRING;
765 params.hapFlags = SELINUX_HAP_DLP;
766 EXPECT_EQ(SELINUX_SUCC, test.HapContextsLookup(params, false, con));
767 EXPECT_STREQ(context_str(con), DLP_HAP_DATA_TYPE.c_str());
768
769 params.apl = NORMAL_APL;
770 params.packageName = EMPTY_STRING;
771 params.hapFlags = SELINUX_HAP_DLP | SELINUX_HAP_DEBUGGABLE;
772 EXPECT_EQ(SELINUX_SUCC, test.HapContextsLookup(params, false, con));
773 EXPECT_STREQ(context_str(con), DLP_HAP_DATA_TYPE.c_str());
774
775 freecon(oldTypeContext);
776 context_free(con);
777 }
778
779 /**
780 * @tc.name: HapContextsLookup003
781 * @tc.desc: test HapContextsLookup must succeed
782 * @tc.type: FUNC
783 * @tc.require: issueI9MCSP
784 */
785 HWTEST_F(SelinuxUnitTest, HapContextsLookup003, TestSize.Level1)
786 {
787 char *oldTypeContext = nullptr;
788 ASSERT_EQ(SELINUX_SUCC, getcon(&oldTypeContext));
789 context_t con = context_new(oldTypeContext);
790 //1.normal
791 HapContextParams params;
792 params.apl = NORMAL_APL;
793 params.packageName = EMPTY_STRING;
794 params.hapFlags = 0;
795 params.extension = TEST_EXTENSION;
796 int res = test.HapContextsLookup(params, true, con);
797 EXPECT_EQ(res, SELINUX_SUCC);
798 EXPECT_STREQ(context_str(con), TEST_EXTENSION_DOMAIN.c_str());
799 //2.debug
800 params.apl = NORMAL_APL;
801 params.packageName = EMPTY_STRING;
802 params.hapFlags = SELINUX_HAP_DEBUGGABLE;
803 params.extension = TEST_DEBUG_EXTENSION;
804 res = test.HapContextsLookup(params, true, con);
805 EXPECT_EQ(res, SELINUX_SUCC);
806 EXPECT_STREQ(context_str(con), TEST_EXTENSION_DEBUG_DOMAIN.c_str());
807 //3.preinstall
808 params.apl = NORMAL_APL;
809 params.packageName = "NOT_SET";
810 params.hapFlags = SELINUX_HAP_RESTORECON_PREINSTALLED_APP;
811 params.extension = "NOT_SET";
812 res = test.HapContextsLookup(params, true, con);
813 EXPECT_EQ(res, SELINUX_SUCC);
814 EXPECT_STREQ(context_str(con), TEST_NORMAL_DOMAIN.c_str());
815 //4.preinstall
816 params.apl = NORMAL_APL;
817 params.packageName = TEST_HAP_BUNDLE_NAME;
818 params.hapFlags = SELINUX_HAP_RESTORECON_PREINSTALLED_APP;
819 params.extension = "NOT_SET";
820 res = test.HapContextsLookup(params, true, con);
821 EXPECT_EQ(res, SELINUX_SUCC);
822 EXPECT_STREQ(context_str(con), TEST_HAP_DOMAIN.c_str());
823
824 freecon(oldTypeContext);
825 context_free(con);
826 }
827
828 /**
829 * @tc.name: HapContextsLookup004
830 * @tc.desc: test HapContextsLookup must succeed
831 * @tc.type: FUNC
832 * @tc.require: issueI9MCSP
833 */
834 HWTEST_F(SelinuxUnitTest, HapContextsLookup004, TestSize.Level1)
835 {
836 char *oldTypeContext = nullptr;
837 ASSERT_EQ(SELINUX_SUCC, getcon(&oldTypeContext));
838 context_t con = context_new(oldTypeContext);
839 HapContextParams params;
840 //5.preinstall
841 params.apl = NORMAL_APL;
842 params.packageName = TEST_HAP_BUNDLE_NAME;
843 params.hapFlags = SELINUX_HAP_RESTORECON_PREINSTALLED_APP;
844 params.extension = TEST_EXTENSION;
845 int res = test.HapContextsLookup(params, true, con);
846 EXPECT_EQ(res, SELINUX_SUCC);
847 EXPECT_STREQ(context_str(con), TEST_EXTENSION_PREINSTALL_DOMAIN.c_str());
848 //6.preinstall
849 params.apl = NORMAL_APL;
850 params.packageName = TEST_HAP_BUNDLE_NAME;
851 params.hapFlags = SELINUX_HAP_RESTORECON_PREINSTALLED_APP;
852 params.extension = "NOT_SET";
853 res = test.HapContextsLookup(params, true, con);
854 EXPECT_EQ(res, SELINUX_SUCC);
855 EXPECT_STREQ(context_str(con), TEST_HAP_DOMAIN.c_str());
856 //7.preinstall
857 params.apl = NORMAL_APL;
858 params.packageName = "NOT_SET";
859 params.hapFlags = SELINUX_HAP_RESTORECON_PREINSTALLED_APP;
860 params.extension = TEST_SAME_EXTENSION;
861 res = test.HapContextsLookup(params, true, con);
862 EXPECT_EQ(res, SELINUX_SUCC);
863 EXPECT_STREQ(context_str(con), TEST_EXTENSION_SAME_DOMAIN.c_str());
864
865 freecon(oldTypeContext);
866 context_free(con);
867 }
868
869 /**
870 * @tc.name: TypeSet001
871 * @tc.desc: test TypeSet type is empty.
872 * @tc.type: FUNC
873 * @tc.require: issueI6JV34
874 */
875 HWTEST_F(SelinuxUnitTest, TypeSet001, TestSize.Level1)
876 {
877 ASSERT_EQ(-SELINUX_ARG_INVALID, test.TypeSet(EMPTY_STRING, nullptr));
878 }
879 } // namespace SelinuxUnitTest
880 } // namespace Security
881 } // namespace OHOS
882