1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * SPDX-License-Identifier: GPL-2.0
4 *
5 * Unless required by applicable law or agreed to in writing, software
6 * distributed under the License is distributed on an "AS IS" BASIS,
7 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8 * See the License for the specific language governing permissions and
9 * limitations under the License.
10 */
11
12 #include <fcntl.h>
13 #include <pthread.h>
14 #include <cstdint>
15 #include <sys/ioctl.h>
16 #include <unistd.h>
17 #include <bits/syscall.h>
18 #include <cstdio>
19 #include "accesstokenidcommon.h"
20
21 namespace OHOS {
22 namespace Kernel {
23 namespace AccessToken {
24 const char *DEVACCESSTOKENID = "/dev/access_token_id";
25
GetTokenid(unsigned long long * token)26 int GetTokenid(unsigned long long *token)
27 {
28 int fd = open(DEVACCESSTOKENID, O_RDWR);
29 if (fd < 0) {
30 return -1;
31 }
32 int ret = ioctl(fd, ACCESS_TOKENID_GET_TOKENID, token);
33 if (ret != 0) {
34 close(fd);
35 return -1;
36 }
37 close(fd);
38 return 0;
39 }
40
SetTokenid(unsigned long long * token)41 int SetTokenid(unsigned long long *token)
42 {
43 int fd = open(DEVACCESSTOKENID, O_RDWR);
44 if (fd < 0) {
45 return -1;
46 }
47 int ret = ioctl(fd, ACCESS_TOKENID_SET_TOKENID, token);
48 if (ret != 0) {
49 close(fd);
50 return -1;
51 }
52 close(fd);
53 return 0;
54 }
55
SetUidAndGrp()56 void SetUidAndGrp()
57 {
58 int ret = 0;
59 size_t groupListSize = LIST_NUM_2;
60 gid_t groupList[LIST_NUM_2] = {ACCESS_TOKEN_GRPID, TEST_VALUE};
61
62 ret = setgroups(groupListSize, groupList);
63 if (ret != 0) {
64 return;
65 }
66
67 ret = setuid(ACCESS_TOKEN_UID);
68 if (ret != 0) {
69 printf("SetUidAndGrp setuid error %d \n", ret);
70 }
71
72 return;
73 }
74
SetUidAndGrpOther()75 void SetUidAndGrpOther()
76 {
77 int ret = 0;
78 size_t groupListSize = LIST_NUM_1;
79 gid_t groupList[LIST_NUM_1] = {ACCESS_TOKEN_OTHER_GRPID};
80
81 ret = setgroups(groupListSize, groupList);
82 if (ret != 0) {
83 return;
84 }
85
86 ret = setuid(ACCESS_TOKEN_OTHER_UID);
87 if (ret != 0) {
88 printf("SetUidAndGrp setuid error %d \n", ret);
89 }
90
91 return;
92 }
93
SetRandTokenAndCheck(const unsigned long long * dataToken)94 void SetRandTokenAndCheck(const unsigned long long *dataToken)
95 {
96 pid_t pid = getpid();
97 pid_t tid = syscall(__NR_gettid);
98 unsigned long long token = INVAL_TOKEN;
99 unsigned long long tokenSet = *dataToken;
100
101 SetTokenid(&tokenSet);
102 GetTokenid(&token);
103
104 if (token != tokenSet) {
105 printf("pid:%d tid:%d token test failed, token:%llu tokenSet:%llu\n",
106 pid, tid, token, tokenSet);
107 } else {
108 printf("pid:%d tid:%d token test succeed, token:%llu tokenSet:%llu\n",
109 pid, tid, token, tokenSet);
110 }
111
112 sleep(WAIT_FOR_SHELL_OP_TIME);
113
114 GetTokenid(&token);
115 if (token != tokenSet) {
116 printf("pid:%d tid:%d token test failed, token:%llu tokenSet:%llu\n",
117 pid, tid, token, tokenSet);
118 } else {
119 printf("pid:%d tid:%d token test succeed, token:%llu tokenSet:%llu\n",
120 pid, tid, token, tokenSet);
121 }
122 return;
123 }
124
TokenTest(void * dataToken)125 void *TokenTest(void *dataToken)
126 {
127 SetRandTokenAndCheck(static_cast<unsigned long long *>(dataToken));
128 return nullptr;
129 }
130
ThreadTest(void * dataToken)131 void ThreadTest(void *dataToken)
132 {
133 pthread_t tid1;
134 pthread_t tid2;
135 pthread_t tid3;
136 int ret = 0;
137
138 ret = pthread_create(&tid1, nullptr, TokenTest, dataToken);
139 if (ret != 0) {
140 return;
141 }
142
143 ret = pthread_create(&tid2, nullptr, TokenTest, dataToken);
144 if (ret != 0) {
145 return;
146 }
147
148 ret = pthread_create(&tid3, nullptr, TokenTest, dataToken);
149 if (ret != 0) {
150 return;
151 }
152
153 pthread_join(tid1, nullptr);
154 pthread_join(tid2, nullptr);
155 pthread_join(tid3, nullptr);
156
157 return;
158 }
159
AccessTokenidThreadTest(uint8_t * dataToken)160 int AccessTokenidThreadTest(uint8_t *dataToken)
161 {
162 TokenTest(static_cast<void *>(dataToken));
163 ThreadTest(static_cast<void *>(dataToken));
164 return 0;
165 }
166
AccessTokenidGrpTest(uint8_t * dataToken)167 int AccessTokenidGrpTest(uint8_t *dataToken)
168 {
169 SetUidAndGrp();
170 TokenTest(static_cast<void *>(dataToken));
171 ThreadTest(static_cast<void *>(dataToken));
172 return 0;
173 }
174
AccessTokenidGrpTestOther(uint8_t * dataToken)175 int AccessTokenidGrpTestOther(uint8_t *dataToken)
176 {
177 SetUidAndGrpOther();
178 TokenTest(static_cast<void *>(dataToken));
179 ThreadTest(static_cast<void *>(dataToken));
180 return 0;
181 }
182
GetfTokenid(unsigned long long * ftoken)183 int GetfTokenid(unsigned long long *ftoken)
184 {
185 int fd = open(DEVACCESSTOKENID, O_RDWR);
186 if (fd < 0) {
187 return -1;
188 }
189
190 int ret = ioctl(fd, ACCESS_TOKENID_GET_FTOKENID, ftoken);
191 if (ret != 0) {
192 close(fd);
193 return -1;
194 }
195
196 close(fd);
197 return 0;
198 }
199
SetfTokenid(unsigned long long * ftoken)200 int SetfTokenid(unsigned long long *ftoken)
201 {
202 int fd = open(DEVACCESSTOKENID, O_RDWR);
203 if (fd < 0) {
204 return -1;
205 }
206
207 int ret = ioctl(fd, ACCESS_TOKENID_SET_FTOKENID, ftoken);
208 if (ret != 0) {
209 close(fd);
210 return -1;
211 }
212
213 close(fd);
214 return 0;
215 }
216
SetRandfTokenAndCheck(const unsigned long long * dataFtoken)217 void SetRandfTokenAndCheck(const unsigned long long *dataFtoken)
218 {
219 pid_t pid = getpid();
220 pid_t tid = syscall(__NR_gettid);
221 unsigned long long ftoken = INVAL_TOKEN;
222 unsigned long long ftokenSet = *dataFtoken;
223
224 SetfTokenid(&ftokenSet);
225 GetfTokenid(&ftoken);
226
227 if (ftoken != ftokenSet) {
228 printf("pid:%d tid:%d ftoken test failed, ftoken:%llu ftokenSet:%llu\n",
229 pid, tid, ftoken, ftokenSet);
230 } else {
231 printf("pid:%d tid:%d ftoken test succeed, ftoken:%llu ftokenSet:%llu\n",
232 pid, tid, ftoken, ftokenSet);
233 }
234
235 sleep(WAIT_FOR_SHELL_OP_TIME);
236
237 GetfTokenid(&ftoken);
238 if (ftoken != ftokenSet) {
239 printf("pid:%d tid:%d ftoken test failed, ftoken:%llu ftokenSet:%llu\n",
240 pid, tid, ftoken, ftokenSet);
241 } else {
242 printf("pid:%d tid:%d ftoken test succeed, ftoken:%llu ftokenSet:%llu\n",
243 pid, tid, ftoken, ftokenSet);
244 }
245 return;
246 }
247
FTokenTest(void * dataFtoken)248 void *FTokenTest(void *dataFtoken)
249 {
250 SetRandfTokenAndCheck(static_cast<unsigned long long *>(dataFtoken));
251 return nullptr;
252 }
253
AccessfTokenidThreadTest(uint8_t * dataFtoken)254 int AccessfTokenidThreadTest(uint8_t *dataFtoken)
255 {
256 FTokenTest(static_cast<void *>(dataFtoken));
257 ThreadTest(static_cast<void *>(dataFtoken));
258 return 0;
259 }
260
AccessfTokenidGrpTest(uint8_t * dataFtoken)261 int AccessfTokenidGrpTest(uint8_t *dataFtoken)
262 {
263 SetUidAndGrp();
264 FTokenTest(static_cast<void *>(dataFtoken));
265 ThreadTest(static_cast<void *>(dataFtoken));
266 return 0;
267 }
268
AccessfTokenidGrpTestOther(uint8_t * dataFtoken)269 int AccessfTokenidGrpTestOther(uint8_t *dataFtoken)
270 {
271 SetUidAndGrpOther();
272 FTokenTest(static_cast<void *>(dataFtoken));
273 ThreadTest(static_cast<void *>(dataFtoken));
274 return 0;
275 }
276
SetfTokenidCmdFuzzTest(const uint8_t * data,size_t size)277 bool SetfTokenidCmdFuzzTest(const uint8_t *data, size_t size)
278 {
279 bool ret = false;
280 if ((data == nullptr) || (size < sizeof(unsigned long long))) {
281 return ret;
282 } else {
283 unsigned long long tokenId = *(reinterpret_cast<const unsigned long long *>(data));
284 ret = SetfTokenid(&tokenId);
285 }
286 return ret;
287 }
288
GetfTokenidCmdFuzzTest(const uint8_t * data,size_t size)289 bool GetfTokenidCmdFuzzTest(const uint8_t *data, size_t size)
290 {
291 bool ret = false;
292 if ((data == nullptr) || (size < sizeof(unsigned long long))) {
293 return ret;
294 } else {
295 unsigned long long tokenId = *(reinterpret_cast<const unsigned long long *>(data));
296 ret = GetfTokenid(&tokenId);
297 }
298 return ret;
299 }
300
GetTokenidCmdFuzzTest(const uint8_t * data,size_t size)301 bool GetTokenidCmdFuzzTest(const uint8_t *data, size_t size)
302 {
303 bool ret = false;
304 if ((data == nullptr) || (size < sizeof(unsigned long long))) {
305 return ret;
306 } else {
307 unsigned long long tokenId = *(reinterpret_cast<const unsigned long long *>(data));
308 ret = GetTokenid(&tokenId);
309 }
310 return ret;
311 }
312
SetTokenidCmdFuzzTest(const uint8_t * data,size_t size)313 bool SetTokenidCmdFuzzTest(const uint8_t *data, size_t size)
314 {
315 bool ret = false;
316 if ((data == nullptr) || (size < sizeof(unsigned long long))) {
317 return ret;
318 } else {
319 unsigned long long tokenId = *(reinterpret_cast<const unsigned long long *>(data));
320 ret = SetTokenid(&tokenId);
321 }
322 return ret;
323 }
324 } // namespace AccessToken
325 } // namespace Kernel
326 } // namespace OHOS
327