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