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