• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
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 using namespace testing::ext;
24 using namespace OHOS::Security::SelinuxUnitTest;
25 using namespace Selinux;
26 const static int SLEEP_SECOND = 2;
27 const static std::string BASE_PATH = "/data/app/el1/0/base/";
28 const static std::string ACCOUNT_PATH = "/data/accounts/account_0/appdata/";
29 const static std::string TEST_HAP_PATH = BASE_PATH + "com.ohos.selftest/";
30 const static std::string TEST_ACCOUNT_PATH = ACCOUNT_PATH + "com.ohos.selftest/";
31 const static std::string TEST_ACCOUNT_SUB_PATH_1_FILE_1 = TEST_ACCOUNT_PATH + "file1.txt";
32 
33 const static std::string TEST_SUB_PATH_1 = TEST_HAP_PATH + "subpath1/";
34 const static std::string TEST_SUB_PATH_2 = TEST_HAP_PATH + "subpath2/";
35 const static std::string TEST_SUB_PATH_3 = TEST_HAP_PATH + "subpath3/";
36 const static std::string TEST_SUB_PATH_4 = TEST_HAP_PATH + "subpath4/";
37 
38 const static std::string TEST_SUB_PATH_1_FILE_1 = TEST_SUB_PATH_1 + "file1.txt";
39 const static std::string TEST_SUB_PATH_1_FILE_2 = TEST_SUB_PATH_1 + "file2.txt";
40 const static std::string TEST_SUB_PATH_2_FILE_1 = TEST_SUB_PATH_2 + "file1.txt";
41 const static std::string TEST_SUB_PATH_2_FILE_2 = TEST_SUB_PATH_2 + "file2.txt";
42 const static std::string TEST_SUB_PATH_3_FILE_1 = TEST_SUB_PATH_3 + "file1.txt";
43 const static std::string TEST_SUB_PATH_3_FILE_2 = TEST_SUB_PATH_3 + "file2.txt";
44 const static std::string TEST_SUB_PATH_4_FILE_1 = TEST_SUB_PATH_4 + "file1.txt";
45 const static std::string TEST_SUB_PATH_4_FILE_2 = TEST_SUB_PATH_4 + "file2.txt";
46 
47 const static std::string TEST_UNSIMPLIFY_PATH = TEST_SUB_PATH_3 + "//../subpath4/";
48 const static std::string TEST_UNSIMPLIFY_FILE = TEST_SUB_PATH_4 + "//../subpath3/file1.txt";
49 
50 const static std::string INVALID_PATH = "/data/data/path";
51 const static std::string EMPTY_STRING = "";
52 const static std::string SYSTEM_CORE_APL = "system_core";
53 const static std::string NORMAL_APL = "normal";
54 const static std::string INVALID_APL = "invalid_apl";
55 
56 const static std::string TEST_HAP_BUNDLE_NAME = "com.hap.selftest";
57 const static std::string TEST_HAP_BUNDLE_NAME_WITH_NO_CONTEXTS = "com.ohos.test";
58 const static std::string TEST_HAP_BUNDLE_NAME_FOR_INVALID_CONTEXTS = "com.hap.selftest_invalid";
59 
60 const static std::string TEST_HAP_DATA_FILE_LABEL = "u:object_r:selftest_hap_data_file:s0";
61 
62 const static std::string TEST_HAP_DOMAIN = "u:r:selftest:s0";
63 
64 const static std::string SEHAP_CONTEXTS_FILE = "/data/test/sehap_contexts";
65 
66 static HapFileInfo g_hapFileInfoWithoutFlags = {
67     .pathNameOrig = {TEST_SUB_PATH_1},
68     .apl = SYSTEM_CORE_APL,
69     .packageName = TEST_HAP_BUNDLE_NAME,
70     .flags = 0,
71     .hapFlags = 1,
72 };
73 
74 static HapFileInfo g_hapFileInfoWithFlags = {
75     .pathNameOrig = {TEST_HAP_PATH},
76     .apl = SYSTEM_CORE_APL,
77     .packageName = TEST_HAP_BUNDLE_NAME,
78     .flags = 1,
79     .hapFlags = 1,
80 };
81 
82 static HapFileInfo g_hapFileInfoWithAplEmpty = {
83     .pathNameOrig = {TEST_HAP_PATH},
84     .apl = "",
85     .packageName = TEST_HAP_BUNDLE_NAME,
86     .flags = 0,
87     .hapFlags = 1,
88 };
89 
90 static HapFileInfo g_hapFileInfoWithPathEmpty = {
91     .pathNameOrig = {},
92     .apl = SYSTEM_CORE_APL,
93     .packageName = TEST_HAP_BUNDLE_NAME,
94     .flags = 0,
95     .hapFlags = 1,
96 };
97 
98 static HapFileInfo g_hapFileInfoWithAplInvalid = {
99     .pathNameOrig = {TEST_HAP_PATH},
100     .apl = INVALID_APL,
101     .packageName = TEST_HAP_BUNDLE_NAME,
102     .flags = 0,
103     .hapFlags = 1,
104 };
105 
106 static HapFileInfo g_hapFileInfoWithCannotFindContexts = {
107     .pathNameOrig = {TEST_HAP_PATH},
108     .apl = SYSTEM_CORE_APL,
109     .packageName = TEST_HAP_BUNDLE_NAME_WITH_NO_CONTEXTS,
110     .flags = 0,
111     .hapFlags = 1,
112 };
113 
114 static HapFileInfo g_hapFileInfoForRepeatLabel = {
115     .pathNameOrig = {TEST_SUB_PATH_1},
116     .apl = SYSTEM_CORE_APL,
117     .packageName = TEST_HAP_BUNDLE_NAME,
118     .flags = 0,
119     .hapFlags = 1,
120 };
121 
122 static HapFileInfo g_hapFileInfoWithPreinstallHap = {
123     .pathNameOrig = {TEST_SUB_PATH_1},
124     .apl = SYSTEM_CORE_APL,
125     .packageName = TEST_HAP_BUNDLE_NAME,
126     .flags = 0,
127     .hapFlags = 0,
128 };
129 
130 static HapFileInfo g_hapFileInfoWithInvalidPath = {
131     .pathNameOrig = {TEST_SUB_PATH_1, INVALID_PATH},
132     .apl = SYSTEM_CORE_APL,
133     .packageName = TEST_HAP_BUNDLE_NAME,
134     .flags = 0,
135     .hapFlags = 1,
136 };
137 
138 static HapFileInfo g_hapFileInfoForInvalidContexts = {
139     .pathNameOrig = {TEST_HAP_PATH},
140     .apl = NORMAL_APL,
141     .packageName = TEST_HAP_BUNDLE_NAME_FOR_INVALID_CONTEXTS,
142     .flags = 0,
143     .hapFlags = 1,
144 };
145 
146 static HapDomainInfo g_hapDomainInfoWithAplEmpty {
147     .apl = "",
148     .packageName = TEST_HAP_BUNDLE_NAME,
149     .hapFlags = 1,
150 };
151 
152 static HapDomainInfo g_hapDomainInfoWithInvalidApl {
153     .apl = INVALID_APL,
154     .packageName = TEST_HAP_BUNDLE_NAME,
155     .hapFlags = 1,
156 };
157 
158 static HapDomainInfo g_hapDomainInfo {
159     .apl = SYSTEM_CORE_APL,
160     .packageName = TEST_HAP_BUNDLE_NAME,
161     .hapFlags = 1,
162 };
163 
164 static HapDomainInfo g_hapDomainInfoForInvalidContexts {
165     .apl = NORMAL_APL,
166     .packageName = TEST_HAP_BUNDLE_NAME_FOR_INVALID_CONTEXTS,
167     .hapFlags = 1,
168 };
169 
GenerateTestFile()170 static void GenerateTestFile()
171 {
172     std::vector<std::string> sehapInfo = {
173         "apl=system_core domain=system_core_hap type=system_core_hap_data_file",
174         "apl=system_basic domain=system_basic_hap type=system_basic_hap_data_file",
175         "apl=normal domain=normal_hap type=normal_hap_data_file",
176         "apl=normal debuggable=true domain=debug_hap type=debug_hap_data_file",
177         "apl=system_core name=com.ohos.test domain= type=",
178         "apl=system_core domain=selftest type=selftest_hap_data_file",
179         "apl=system_core name=com.hap.selftest domain=selftest type=selftest_hap_data_file",
180         "apl=normal name=com.hap.selftest domain=selftest type=normal_hap_data_file",
181         "apl=normal name=com.hap.selftest_invalid domain=selftest_invalid type=selftest_invalid_hap_data_file"};
182     ASSERT_EQ(true, WriteFile(SEHAP_CONTEXTS_FILE, sehapInfo));
183 }
184 
RemoveTestFile()185 static void RemoveTestFile()
186 {
187     unlink(SEHAP_CONTEXTS_FILE.c_str());
188 }
189 
SetUpTestCase()190 void SelinuxUnitTest::SetUpTestCase()
191 {
192     // make test case clean
193     GenerateTestFile();
194 }
195 
TearDownTestCase()196 void SelinuxUnitTest::TearDownTestCase()
197 {
198     RemoveTestFile();
199 }
200 
SetUp()201 void SelinuxUnitTest::SetUp() {}
202 
TearDown()203 void SelinuxUnitTest::TearDown() {}
204 
CreateDataFile() const205 void SelinuxUnitTest::CreateDataFile() const {}
206 
207 /**
208  * @tc.name: HapFileRestorecon001
209  * @tc.desc: test HapFileRestorecon input para invalid.
210  * @tc.type: FUNC
211  * @tc.require: AR000GJSDQ
212  */
213 HWTEST_F(SelinuxUnitTest, HapFileRestorecon001, TestSize.Level1)
214 {
215     ASSERT_EQ(true, CreateDirectory(TEST_HAP_PATH));
216 
217     EXPECT_EQ(-SELINUX_ARG_INVALID, test.HapFileRestorecon(g_hapFileInfoWithAplEmpty));
218 
219     EXPECT_EQ(-SELINUX_ARG_INVALID, test.HapFileRestorecon(g_hapFileInfoWithPathEmpty));
220 
221     EXPECT_EQ(-SELINUX_ARG_INVALID, test.HapFileRestorecon(g_hapFileInfoWithAplInvalid));
222 
223     ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
224 }
225 
226 /**
227  * @tc.name: HapFileRestorecon002
228  * @tc.desc: test HapFileRestorecon normal branch without restorecon.
229  * @tc.type: FUNC
230  * @tc.require:AR000GJSDQ
231  */
232 HWTEST_F(SelinuxUnitTest, HapFileRestorecon002, TestSize.Level1)
233 {
234     ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_1_FILE_1)); // this file should not be restorecon
235 
236     char *secontextOld = nullptr;
237     getfilecon(TEST_SUB_PATH_1_FILE_1.c_str(), &secontextOld);
238 
239     int ret = test.HapFileRestorecon(g_hapFileInfoWithoutFlags);
240     ASSERT_EQ(SELINUX_SUCC, ret);
241 
242     char *secontextNew = nullptr;
243     getfilecon(TEST_SUB_PATH_1.c_str(), &secontextNew);
244     EXPECT_STREQ(TEST_HAP_DATA_FILE_LABEL.c_str(), secontextNew);
245     freecon(secontextNew);
246     secontextNew = nullptr;
247 
248     getfilecon(TEST_SUB_PATH_1_FILE_1.c_str(), &secontextNew);
249     EXPECT_STREQ(secontextOld, secontextNew);
250     freecon(secontextNew);
251     secontextNew = nullptr;
252 
253     ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
254 }
255 
256 /**
257  * @tc.name: HapFileRestorecon003
258  * @tc.desc: test HapFileRestorecon normal branch with restorecon.
259  * @tc.type: FUNC
260  * @tc.require:AR000GJSDQ
261  */
262 HWTEST_F(SelinuxUnitTest, HapFileRestorecon003, TestSize.Level1)
263 {
264     ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_1_FILE_1));
265     ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_1_FILE_2));
266     ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_2_FILE_1));
267     ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_2_FILE_2));
268 
269     int ret = test.HapFileRestorecon(g_hapFileInfoWithFlags);
270     ASSERT_EQ(SELINUX_SUCC, ret);
271 
272     char *secontext = nullptr;
273     getfilecon(TEST_SUB_PATH_1.c_str(), &secontext);
274     EXPECT_STREQ(TEST_HAP_DATA_FILE_LABEL.c_str(), secontext);
275     freecon(secontext);
276     secontext = nullptr;
277 
278     getfilecon(TEST_SUB_PATH_2.c_str(), &secontext);
279     EXPECT_STREQ(TEST_HAP_DATA_FILE_LABEL.c_str(), secontext);
280     freecon(secontext);
281     secontext = nullptr;
282 
283     getfilecon(TEST_SUB_PATH_1_FILE_1.c_str(), &secontext);
284     EXPECT_STREQ(TEST_HAP_DATA_FILE_LABEL.c_str(), secontext);
285     freecon(secontext);
286     secontext = nullptr;
287 
288     getfilecon(TEST_SUB_PATH_1_FILE_2.c_str(), &secontext);
289     EXPECT_STREQ(TEST_HAP_DATA_FILE_LABEL.c_str(), secontext);
290     freecon(secontext);
291     secontext = nullptr;
292 
293     getfilecon(TEST_SUB_PATH_2_FILE_1.c_str(), &secontext);
294     EXPECT_STREQ(TEST_HAP_DATA_FILE_LABEL.c_str(), secontext);
295     freecon(secontext);
296     secontext = nullptr;
297 
298     getfilecon(TEST_SUB_PATH_2_FILE_2.c_str(), &secontext);
299     EXPECT_STREQ(TEST_HAP_DATA_FILE_LABEL.c_str(), secontext);
300     freecon(secontext);
301     secontext = nullptr;
302 
303     ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
304 }
305 
306 /**
307  * @tc.name: HapFileRestorecon004
308  * @tc.desc: test HapFileRestorecon with single path input para invalid.
309  * @tc.type: FUNC
310  * @tc.require: AR000GJSDQ
311  */
312 HWTEST_F(SelinuxUnitTest, HapFileRestorecon004, TestSize.Level1)
313 {
314     ASSERT_EQ(true, CreateDirectory(TEST_HAP_PATH));
315 
316     EXPECT_EQ(-SELINUX_ARG_INVALID, test.HapFileRestorecon(TEST_HAP_PATH, g_hapFileInfoWithAplEmpty));
317 
318     EXPECT_EQ(-SELINUX_ARG_INVALID, test.HapFileRestorecon(EMPTY_STRING, g_hapFileInfoWithPathEmpty));
319 
320     EXPECT_EQ(-SELINUX_ARG_INVALID, test.HapFileRestorecon(TEST_HAP_PATH, g_hapFileInfoWithAplInvalid));
321 
322     EXPECT_EQ(-SELINUX_CHECK_CONTEXT_ERROR, test.HapFileRestorecon(TEST_HAP_PATH, g_hapFileInfoForInvalidContexts));
323 
324     ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
325 }
326 
327 /**
328  * @tc.name: HapFileRestorecon005
329  * @tc.desc: test HapFileRestorecon with no recurce.
330  * @tc.type: FUNC
331  * @tc.require: AR000GJSDQ
332  */
333 HWTEST_F(SelinuxUnitTest, HapFileRestorecon005, TestSize.Level1)
334 {
335     ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_1_FILE_1));
336 
337     EXPECT_EQ(SELINUX_SUCC, test.HapFileRestorecon(TEST_HAP_PATH, g_hapFileInfoWithoutFlags));
338 
339     ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
340 }
341 
342 /**
343  * @tc.name: HapFileRestorecon006
344  * @tc.desc: test HapFileRestorecon checkPath fail.
345  * @tc.type: FUNC
346  * @tc.require: AR000GJSDQ
347  */
348 HWTEST_F(SelinuxUnitTest, HapFileRestorecon006, TestSize.Level1)
349 {
350     ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_1_FILE_1));
351 
352     EXPECT_EQ(-SELINUX_PATH_INVAILD, test.HapFileRestorecon(INVALID_PATH, g_hapFileInfoWithoutFlags));
353 
354     ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
355 }
356 
357 /**
358  * @tc.name: HapFileRestorecon007
359  * @tc.desc: test HapFileRestorecon with accounts path.
360  * @tc.type: FUNC
361  * @tc.require: AR000GJSDQ
362  */
363 HWTEST_F(SelinuxUnitTest, HapFileRestorecon007, TestSize.Level1)
364 {
365     ASSERT_EQ(true, CreateFile(TEST_ACCOUNT_SUB_PATH_1_FILE_1));
366 
367     EXPECT_EQ(SELINUX_SUCC, test.HapFileRestorecon(TEST_ACCOUNT_SUB_PATH_1_FILE_1, g_hapFileInfoWithoutFlags));
368 
369     ASSERT_EQ(true, RemoveDirectory(ACCOUNT_PATH));
370 }
371 
372 /**
373  * @tc.name: HapFileRestorecon008
374  * @tc.desc: test HapFileRestorecon type is empty.
375  * @tc.type: FUNC
376  * @tc.require: AR000GJSDQ
377  */
378 HWTEST_F(SelinuxUnitTest, HapFileRestorecon008, TestSize.Level1)
379 {
380     ASSERT_EQ(true, CreateDirectory(TEST_HAP_PATH));
381 
382     EXPECT_EQ(-SELINUX_KEY_NOT_FOUND, test.HapFileRestorecon(TEST_HAP_PATH, g_hapFileInfoWithCannotFindContexts));
383 
384     ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
385 }
386 
CompareContexts(const std::string & path,const std::string & label)387 static bool CompareContexts(const std::string &path, const std::string &label)
388 {
389     char *secontext = nullptr;
390     getfilecon(path.c_str(), &secontext);
391     bool res = (strcmp(label.c_str(), secontext) == 0);
392     freecon(secontext);
393     secontext = nullptr;
394     return res;
395 }
396 
397 /**
398  * @tc.name: HapFileRestorecon009
399  * @tc.desc: test HapFileRestorecon input multi path/file no recurse.
400  * @tc.type: FUNC
401  * @tc.require:AR000GJSDQ
402  */
403 HWTEST_F(SelinuxUnitTest, HapFileRestorecon009, TestSize.Level1)
404 {
405     ASSERT_EQ(true, CreateDirectory(TEST_SUB_PATH_4));
406     ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_1_FILE_1));
407     ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_1_FILE_2));
408     ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_2_FILE_1)); // should not be restorecon
409     ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_3_FILE_1));
410 
411     char *secontextOld = nullptr;
412     getfilecon(TEST_SUB_PATH_2_FILE_1.c_str(), &secontextOld);
413 
414     HapFileInfo hapFileInfo = {
415         .pathNameOrig = {TEST_SUB_PATH_1, TEST_SUB_PATH_2, TEST_SUB_PATH_1_FILE_1, TEST_SUB_PATH_1_FILE_2,
416                          TEST_UNSIMPLIFY_FILE, TEST_UNSIMPLIFY_PATH},
417         .apl = SYSTEM_CORE_APL,
418         .packageName = TEST_HAP_BUNDLE_NAME,
419         .flags = 0,
420         .hapFlags = 1,
421     };
422 
423     ASSERT_EQ(SELINUX_SUCC, test.HapFileRestorecon(hapFileInfo));
424     EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_1, TEST_HAP_DATA_FILE_LABEL));
425     EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_2, TEST_HAP_DATA_FILE_LABEL));
426     EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_1_FILE_1, TEST_HAP_DATA_FILE_LABEL));
427     EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_1_FILE_2, TEST_HAP_DATA_FILE_LABEL));
428     EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_3_FILE_1, TEST_HAP_DATA_FILE_LABEL));
429     EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_4, TEST_HAP_DATA_FILE_LABEL));
430 
431     char *secontext = nullptr;
432     getfilecon(TEST_SUB_PATH_2_FILE_1.c_str(), &secontext); // this file should not be restorecon
433     EXPECT_STREQ(secontextOld, secontext);
434     freecon(secontext);
435     freecon(secontextOld);
436     secontext = nullptr;
437     secontextOld = nullptr;
438 
439     ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
440 }
441 
442 /**
443  * @tc.name: HapFileRestorecon010
444  * @tc.desc: test HapFileRestorecon input multi path/file recurse.
445  * @tc.type: FUNC
446  * @tc.require:AR000GJSDQ
447  */
448 HWTEST_F(SelinuxUnitTest, HapFileRestorecon010, TestSize.Level1)
449 {
450     ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_1_FILE_1));
451     ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_1_FILE_2));
452     ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_2_FILE_1));
453     ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_2_FILE_2));
454     ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_3_FILE_1));
455     ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_3_FILE_2)); // this file should not be restorecon
456     ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_4_FILE_1));
457     ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_4_FILE_2));
458 
459     char *secontextOld = nullptr;
460     getfilecon(TEST_SUB_PATH_3_FILE_2.c_str(), &secontextOld);
461 
462     HapFileInfo hapFileInfo = {
463         .pathNameOrig = { TEST_SUB_PATH_1, TEST_SUB_PATH_2, TEST_UNSIMPLIFY_FILE, TEST_UNSIMPLIFY_PATH },
464         .apl = SYSTEM_CORE_APL,
465         .packageName = TEST_HAP_BUNDLE_NAME,
466         .flags = 1,
467         .hapFlags = 1,
468     };
469     ASSERT_EQ(SELINUX_SUCC, test.HapFileRestorecon(hapFileInfo));
470     EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_1, TEST_HAP_DATA_FILE_LABEL));
471     EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_2, TEST_HAP_DATA_FILE_LABEL));
472     EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_4, TEST_HAP_DATA_FILE_LABEL));
473     EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_1_FILE_1, TEST_HAP_DATA_FILE_LABEL));
474     EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_1_FILE_2, TEST_HAP_DATA_FILE_LABEL));
475     EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_2_FILE_1, TEST_HAP_DATA_FILE_LABEL));
476     EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_2_FILE_2, TEST_HAP_DATA_FILE_LABEL));
477     EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_4_FILE_1, TEST_HAP_DATA_FILE_LABEL));
478     EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_4_FILE_2, TEST_HAP_DATA_FILE_LABEL));
479     EXPECT_TRUE(CompareContexts(TEST_SUB_PATH_3_FILE_1, TEST_HAP_DATA_FILE_LABEL));
480 
481     char *secontext = nullptr;
482     getfilecon(TEST_SUB_PATH_3_FILE_2.c_str(), &secontext);
483     EXPECT_STREQ(secontextOld, secontext);
484     freecon(secontext);
485     freecon(secontextOld);
486     secontext = nullptr;
487     secontextOld = nullptr;
488 
489     ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
490 }
491 
492 /**
493  * @tc.name: HapFileRestorecon011
494  * @tc.desc: test HapFileRestorecon repeat label.
495  * @tc.type: FUNC
496  * @tc.require:AR000GJSDQ
497  */
498 HWTEST_F(SelinuxUnitTest, HapFileRestorecon011, TestSize.Level1)
499 {
500     ASSERT_EQ(true, CreateDirectory(TEST_SUB_PATH_1));
501     int ret = test.HapFileRestorecon(g_hapFileInfoForRepeatLabel);
502     ASSERT_EQ(SELINUX_SUCC, ret);
503 
504     char *secontext = nullptr;
505     getfilecon(TEST_SUB_PATH_1.c_str(), &secontext);
506     EXPECT_STREQ(TEST_HAP_DATA_FILE_LABEL.c_str(), secontext);
507     freecon(secontext);
508     secontext = nullptr;
509 
510     char *secontextOld = nullptr;
511     getfilecon(TEST_SUB_PATH_1.c_str(), &secontextOld);
512 
513     ret = test.HapFileRestorecon(g_hapFileInfoForRepeatLabel); // double restorcon
514     ASSERT_EQ(SELINUX_SUCC, ret);
515 
516     getfilecon(TEST_SUB_PATH_1.c_str(), &secontext);
517     EXPECT_STREQ(secontextOld, secontext);
518     freecon(secontext);
519     freecon(secontextOld);
520     secontext = nullptr;
521     secontextOld = nullptr;
522 
523     ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
524 }
525 
526 /**
527  * @tc.name: HapFileRestorecon012
528  * @tc.desc: test HapFileRestorecon normal branch with preinstalled app.
529  * @tc.type: FUNC
530  * @tc.require:AR000GJSDQ
531  */
532 HWTEST_F(SelinuxUnitTest, HapFileRestorecon012, TestSize.Level1)
533 {
534     ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_1_FILE_1));
535 
536     int ret = test.HapFileRestorecon(g_hapFileInfoWithPreinstallHap);
537     ASSERT_EQ(SELINUX_SUCC, ret);
538 
539     char *secontextNew = nullptr;
540     getfilecon(TEST_SUB_PATH_1.c_str(), &secontextNew);
541     EXPECT_STREQ(TEST_HAP_DATA_FILE_LABEL.c_str(), secontextNew);
542     freecon(secontextNew);
543     secontextNew = nullptr;
544 
545     ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
546 }
547 
548 /**
549  * @tc.name: HapFileRestorecon013
550  * @tc.desc: test HapFileRestorecon with multi path failed.
551  * @tc.type: FUNC
552  * @tc.require:
553  */
554 HWTEST_F(SelinuxUnitTest, HapFileRestorecon013, TestSize.Level1)
555 {
556     ASSERT_EQ(true, CreateFile(TEST_SUB_PATH_1_FILE_1));
557     ASSERT_EQ(true, CreateFile(INVALID_PATH));
558 
559     ASSERT_EQ(-SELINUX_RESTORECON_ERROR, test.HapFileRestorecon(g_hapFileInfoWithInvalidPath));
560 
561     ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
562     ASSERT_EQ(true, RemoveDirectory(INVALID_PATH));
563 }
564 
565 /**
566  * @tc.name: HapFileRecurseRestorecon001
567  * @tc.desc: test HapFileRecurseRestorecon realPath is nullptr.
568  * @tc.type: FUNC
569  * @tc.require: AR000GJSDQ
570  */
571 HWTEST_F(SelinuxUnitTest, HapFileRecurseRestorecon001, TestSize.Level1)
572 {
573     int ret = test.HapFileRecurseRestorecon(nullptr, g_hapFileInfoWithCannotFindContexts);
574     ASSERT_EQ(-SELINUX_FTS_OPEN_ERROR, ret);
575 }
576 
577 /**
578  * @tc.name: RestoreconSb001
579  * @tc.desc: test RestoreconSb with repeat label.
580  * @tc.type: FUNC
581  * @tc.require: AR000GJSDQ
582  */
583 HWTEST_F(SelinuxUnitTest, RestoreconSb001, TestSize.Level1)
584 {
585     ASSERT_EQ(true, CreateDirectory(TEST_SUB_PATH_1));
586 
587     ASSERT_EQ(SELINUX_SUCC, test.RestoreconSb(TEST_SUB_PATH_1, g_hapFileInfoForRepeatLabel));
588     char *secontextOld = nullptr;
589     getfilecon(TEST_SUB_PATH_1.c_str(), &secontextOld);
590     EXPECT_STREQ(secontextOld, TEST_HAP_DATA_FILE_LABEL.c_str());
591     freecon(secontextOld);
592 
593     ASSERT_EQ(SELINUX_SUCC, test.RestoreconSb(TEST_SUB_PATH_1, g_hapFileInfoForRepeatLabel)); // double restorcon
594     char *secontextNew = nullptr;
595     getfilecon(TEST_SUB_PATH_1.c_str(), &secontextNew);
596     EXPECT_STREQ(secontextNew, TEST_HAP_DATA_FILE_LABEL.c_str());
597     freecon(secontextNew);
598 
599     ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
600 }
601 
602 /**
603  * @tc.name: HapDomainSetcontext001
604  * @tc.desc: test HapDomainSetcontext input para invalid.
605  * @tc.type: FUNC
606  * @tc.require: issueI6JV34
607  */
608 HWTEST_F(SelinuxUnitTest, HapDomainSetcontext001, TestSize.Level1)
609 {
610     ASSERT_EQ(true, CreateDirectory(TEST_HAP_PATH));
611 
612     EXPECT_EQ(-SELINUX_ARG_INVALID, test.HapDomainSetcontext(g_hapDomainInfoWithAplEmpty));
613     EXPECT_EQ(-SELINUX_ARG_INVALID, test.HapDomainSetcontext(g_hapDomainInfoWithInvalidApl));
614 
615     ASSERT_EQ(true, RemoveDirectory(TEST_HAP_PATH));
616 }
617 
618 /**
619  * @tc.name: HapDomainSetcontext002
620  * @tc.desc: test HapDomainSetcontext must succeed
621  * @tc.type: FUNC
622  * @tc.require: issueI6JV34
623  */
624 HWTEST_F(SelinuxUnitTest, HapDomainSetcontext002, TestSize.Level1)
625 {
626     pid_t pid = fork();
627     ASSERT_TRUE(pid >= 0);
628     if (pid == 0) {
629         EXPECT_EQ(SELINUX_SUCC, test.HapDomainSetcontext(g_hapDomainInfo));
630         usleep(200000); // sleep 200ms
631         exit(0);
632     } else {
633         usleep(150000); // sleep 150ms
634         char *con = nullptr;
635         ASSERT_EQ(0, getpidcon(pid, &con));
636         EXPECT_STREQ(con, TEST_HAP_DOMAIN.c_str());
637         freecon(con);
638     }
639 }
640 
641 /**
642  * @tc.name: HapDomainSetcontext003
643  * @tc.desc: test HapDomainSetcontext setcon normal_hap.
644  * @tc.type: FUNC
645  * @tc.require: issueI6JV34
646  */
647 HWTEST_F(SelinuxUnitTest, HapDomainSetcontext003, TestSize.Level1)
648 {
649     pid_t pid = fork();
650     ASSERT_TRUE(pid >= 0);
651     if (pid == 0) {
652         EXPECT_EQ(-SELINUX_CHECK_CONTEXT_ERROR, test.HapDomainSetcontext(g_hapDomainInfoForInvalidContexts));
653         exit(0);
654     }
655 }
656 
657 /**
658  * @tc.name: TypeSet001
659  * @tc.desc: test TypeSet type is empty.
660  * @tc.type: FUNC
661  * @tc.require: issueI6JV34
662  */
663 HWTEST_F(SelinuxUnitTest, TypeSet001, TestSize.Level1)
664 {
665     ASSERT_EQ(-SELINUX_ARG_INVALID, test.TypeSet(EMPTY_STRING, nullptr));
666 }
667