• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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