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