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 <selinux/selinux.h>
18 #include "selinux_error.h"
19 #include "selinux_parameter.h"
20 #include "test_common.h"
21
22 using namespace testing::ext;
23 using namespace OHOS::Security::SelinuxUnitTest;
24 using namespace Selinux;
25 const static std::string PARAM_CONTEXTS_FILE = "/system/etc/selinux/targeted/contexts/parameter_contexts";
26 const static std::string DEFAULT_CONTEXT = "u:object_r:default_param:s0";
27 const static std::string TEST_PARA_NAME = "test.para";
28 const static std::string TEST_NOT_EXIST_PARA_NAME = "unittest.not.exist";
29 const static std::string TEST_PARA_CONTEXT = "u:object_r:testpara:s0";
30 const static std::string DEFAULT_PARA_CONTEXT = "u:object_r:default_param:s0";
31
32 const static std::vector<std::string> TEST_INVALID_PARA = {{".test"}, {"test."}, {"test..test"}, {""}, {"test+test"}};
33
GenerateTestFile()34 static void GenerateTestFile()
35 {
36 ASSERT_EQ(true, CopyFile(PARAM_CONTEXTS_FILE, PARAM_CONTEXTS_FILE + "_bk"));
37 std::vector<std::string> paramInfo = {"test.para u:object_r:testpara:s0"};
38 ASSERT_EQ(true, WriteFile(PARAM_CONTEXTS_FILE, paramInfo));
39 }
40
RemoveTestFile()41 static void RemoveTestFile()
42 {
43 ASSERT_EQ(0, RenameFile(PARAM_CONTEXTS_FILE + "_bk", PARAM_CONTEXTS_FILE));
44 }
45
SetUpTestCase()46 void SelinuxUnitTest::SetUpTestCase()
47 {
48 // make test case clean
49 GenerateTestFile();
50 InitParamSelinux();
51 }
52
TearDownTestCase()53 void SelinuxUnitTest::TearDownTestCase()
54 {
55 RemoveTestFile();
56 }
57
SetUp()58 void SelinuxUnitTest::SetUp() {}
59
TearDown()60 void SelinuxUnitTest::TearDown() {}
61
CreateDataFile() const62 void SelinuxUnitTest::CreateDataFile() const {}
63
64 /**
65 * @tc.name: GetParamList001
66 * @tc.desc: GetParamList test.
67 * @tc.type: FUNC
68 * @tc.require:AR000GJSDS
69 */
70 HWTEST_F(SelinuxUnitTest, GetParamList001, TestSize.Level1)
71 {
72 ParamContextsList *buff = nullptr;
73 buff = GetParamList();
74 ASSERT_NE(nullptr, buff);
75 ParamContextsList *head = buff;
76 bool find = false;
77 while (buff != nullptr) {
78 if (std::string(buff->info.paraName) == TEST_PARA_NAME &&
79 std::string(buff->info.paraContext) == TEST_PARA_CONTEXT) {
80 find = true;
81 buff = buff->next;
82 continue;
83 }
84 ASSERT_EQ(SELINUX_SUCC, security_check_context(buff->info.paraContext));
85 buff = buff->next;
86 }
87 ASSERT_EQ(true, find);
88
89 DestroyParamList(&head);
90 ASSERT_EQ(nullptr, head);
91 }
92
93 /**
94 * @tc.name: DestroyParamList001
95 * @tc.desc: DestroyParamList input invalid.
96 * @tc.type: FUNC
97 * @tc.require:AR000GJSDS
98 */
99 HWTEST_F(SelinuxUnitTest, DestroyParamList001, TestSize.Level1)
100 {
101 DestroyParamList(nullptr);
102 }
103
104 /**
105 * @tc.name: GetParamLabel001
106 * @tc.desc: GetParamLabel input invalid.
107 * @tc.type: FUNC
108 * @tc.require:AR000GJSDS
109 */
110 HWTEST_F(SelinuxUnitTest, GetParamLabel001, TestSize.Level1)
111 {
112 ASSERT_EQ(DEFAULT_CONTEXT, GetParamLabel(nullptr));
113
114 for (auto para : TEST_INVALID_PARA) {
115 ASSERT_EQ(DEFAULT_CONTEXT, GetParamLabel(para.c_str()));
116 }
117
118 ASSERT_EQ(DEFAULT_CONTEXT, GetParamLabel(TEST_NOT_EXIST_PARA_NAME.c_str()));
119 }
120
121 /**
122 * @tc.name: GetParamLabel002
123 * @tc.desc: GetParamLabel func test.
124 * @tc.type: FUNC
125 * @tc.require:AR000GJSDS
126 */
127 HWTEST_F(SelinuxUnitTest, GetParamLabel002, TestSize.Level1)
128 {
129 ASSERT_EQ(TEST_PARA_CONTEXT, GetParamLabel(TEST_PARA_NAME.c_str()));
130 }
131
132 /**
133 * @tc.name: ReadParamCheck001
134 * @tc.desc: ReadParamCheck input invalid.
135 * @tc.type: FUNC
136 * @tc.require:AR000GJSDS
137 */
138 HWTEST_F(SelinuxUnitTest, ReadParamCheck001, TestSize.Level1)
139 {
140 ASSERT_EQ(-SELINUX_PTR_NULL, ReadParamCheck(nullptr));
141
142 ASSERT_EQ(SELINUX_SUCC, ReadParamCheck(TEST_NOT_EXIST_PARA_NAME.c_str()));
143
144 std::string cmd = "dmesg | grep 'avc: denied { read } for parameter=" + TEST_NOT_EXIST_PARA_NAME +
145 " pid=" + std::to_string(getpid()) + "' | grep 'tcontext=" + DEFAULT_PARA_CONTEXT +
146 " tclass=file'";
147 std::string cmdRes = RunCommand(cmd);
148 ASSERT_TRUE(cmdRes.find(TEST_NOT_EXIST_PARA_NAME) != std::string::npos);
149
150 for (auto para : TEST_INVALID_PARA) {
151 ASSERT_EQ(SELINUX_SUCC, ReadParamCheck(para.c_str()));
152 }
153 }
154
155 /**
156 * @tc.name: ReadParamCheck002
157 * @tc.desc: ReadParamCheck func test.
158 * @tc.type: FUNC
159 * @tc.require:AR000GJSDS
160 */
161 HWTEST_F(SelinuxUnitTest, ReadParamCheck002, TestSize.Level1)
162 {
163 ASSERT_EQ(SELINUX_SUCC, ReadParamCheck(TEST_PARA_NAME.c_str()));
164 std::string cmd = "dmesg | grep 'avc: denied { read } for parameter=" + TEST_PARA_NAME +
165 " pid=" + std::to_string(getpid()) + "' | grep 'tcontext=" + TEST_PARA_CONTEXT + " tclass=file'";
166 std::string cmdRes = RunCommand(cmd);
167 ASSERT_TRUE(cmdRes.find(TEST_PARA_NAME) != std::string::npos);
168 }
169
170 /**
171 * @tc.name: SetParamCheck001
172 * @tc.desc: SetParamCheck input invalid.
173 * @tc.type: FUNC
174 * @tc.require:AR000GJSDS
175 */
176 HWTEST_F(SelinuxUnitTest, SetParamCheck001, TestSize.Level1)
177 {
178 SrcInfo info;
179 info.uc.pid = getpid();
180 info.uc.uid = getuid();
181 info.uc.gid = getgid();
182 int fd[2];
183 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fd) < 0) {
184 perror("socketpair");
185 exit(EXIT_FAILURE);
186 }
187 info.sockFd = fd[0]
188
189 ASSERT_EQ(-SELINUX_PTR_NULL, SetParamCheck(nullptr, &info));
190
191 ASSERT_EQ(-SELINUX_PTR_NULL, SetParamCheck(TEST_NOT_EXIST_PARA_NAME.c_str(), nullptr));
192
193 ASSERT_EQ(SELINUX_SUCC, SetParamCheck(TEST_NOT_EXIST_PARA_NAME.c_str(), &info));
194 std::string cmd = "dmesg | grep 'avc: denied { set } for parameter=" + TEST_NOT_EXIST_PARA_NAME +
195 " pid=" + std::to_string(getpid()) + "' | grep 'tcontext=" + DEFAULT_PARA_CONTEXT +
196 " tclass=parameter_service'";
197 std::string cmdRes = RunCommand(cmd);
198 ASSERT_TRUE(cmdRes.find(TEST_NOT_EXIST_PARA_NAME) != std::string::npos);
199
200 for (auto para : TEST_INVALID_PARA) {
201 ASSERT_EQ(SELINUX_SUCC, SetParamCheck(para.c_str(), &info));
202 }
203 close(fd[0]);
204 close(fd[1]);
205 }
206
207 /**
208 * @tc.name: SetParamCheck002
209 * @tc.desc: SetParamCheck func test.
210 * @tc.type: FUNC
211 * @tc.require:AR000GJSDS
212 */
213 HWTEST_F(SelinuxUnitTest, SetParamCheck002, TestSize.Level1)
214 {
215 struct ucred uc;
216 uc.pid = getpid();
217 uc.uid = getuid();
218 uc.gid = getgid();
219 ASSERT_EQ(SELINUX_SUCC, SetParamCheck(TEST_PARA_NAME.c_str(), &uc));
220 std::string cmd = "dmesg | grep 'avc: denied { set } for parameter=" + TEST_PARA_NAME +
221 " pid=" + std::to_string(getpid()) + "' | grep 'tcontext=" + TEST_PARA_CONTEXT +
222 " tclass=parameter_service'";
223 std::string cmdRes = RunCommand(cmd);
224 ASSERT_TRUE(cmdRes.find(TEST_PARA_NAME) != std::string::npos);
225 }
226