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 21namespace OHOS { 22namespace Kernel { 23namespace AccessToken { 24const char *g_devaccesstokenid = "/dev/access_token_id"; 25 26int GetTokenid(unsigned long long *token) 27{ 28 int fd = open(g_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 41int SetTokenid(unsigned long long *token) 42{ 43 int fd = open(g_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 56void 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 75void 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 94void 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 125void *TokenTest(void *dataToken) 126{ 127 SetRandTokenAndCheck(static_cast<unsigned long long *>(dataToken)); 128 return nullptr; 129} 130 131void 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 160int AccessTokenidThreadTest(uint8_t *dataToken) 161{ 162 TokenTest(static_cast<void *>(dataToken)); 163 ThreadTest(static_cast<void *>(dataToken)); 164 return 0; 165} 166 167int AccessTokenidGrpTest(uint8_t *dataToken) 168{ 169 SetUidAndGrp(); 170 TokenTest(static_cast<void *>(dataToken)); 171 ThreadTest(static_cast<void *>(dataToken)); 172 return 0; 173} 174 175int AccessTokenidGrpTestOther(uint8_t *dataToken) 176{ 177 SetUidAndGrpOther(); 178 TokenTest(static_cast<void *>(dataToken)); 179 ThreadTest(static_cast<void *>(dataToken)); 180 return 0; 181} 182 183int GetfTokenid(unsigned long long *ftoken) 184{ 185 int fd = open(g_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 200int SetfTokenid(unsigned long long *ftoken) 201{ 202 int fd = open(g_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 217void 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 248void *FTokenTest(void *dataFtoken) 249{ 250 SetRandfTokenAndCheck(static_cast<unsigned long long *>(dataFtoken)); 251 return nullptr; 252} 253 254int AccessfTokenidThreadTest(uint8_t *dataFtoken) 255{ 256 FTokenTest(static_cast<void *>(dataFtoken)); 257 ThreadTest(static_cast<void *>(dataFtoken)); 258 return 0; 259} 260 261int AccessfTokenidGrpTest(uint8_t *dataFtoken) 262{ 263 SetUidAndGrp(); 264 FTokenTest(static_cast<void *>(dataFtoken)); 265 ThreadTest(static_cast<void *>(dataFtoken)); 266 return 0; 267} 268 269int AccessfTokenidGrpTestOther(uint8_t *dataFtoken) 270{ 271 SetUidAndGrpOther(); 272 FTokenTest(static_cast<void *>(dataFtoken)); 273 ThreadTest(static_cast<void *>(dataFtoken)); 274 return 0; 275} 276 277bool 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 289bool 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 301bool 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 313bool 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