13298bea7Sopenharmony_ci/*
23298bea7Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
33298bea7Sopenharmony_ci * SPDX-License-Identifier: GPL-2.0
43298bea7Sopenharmony_ci *
53298bea7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
63298bea7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
73298bea7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
83298bea7Sopenharmony_ci * See the License for the specific language governing permissions and
93298bea7Sopenharmony_ci * limitations under the License.
103298bea7Sopenharmony_ci */
113298bea7Sopenharmony_ci
123298bea7Sopenharmony_ci#include <fcntl.h>
133298bea7Sopenharmony_ci#include <pthread.h>
143298bea7Sopenharmony_ci#include <cstdint>
153298bea7Sopenharmony_ci#include <sys/ioctl.h>
163298bea7Sopenharmony_ci#include <unistd.h>
173298bea7Sopenharmony_ci#include <bits/syscall.h>
183298bea7Sopenharmony_ci#include <cstdio>
193298bea7Sopenharmony_ci#include "accesstokenidcommon.h"
203298bea7Sopenharmony_ci
213298bea7Sopenharmony_cinamespace OHOS {
223298bea7Sopenharmony_cinamespace Kernel {
233298bea7Sopenharmony_cinamespace AccessToken {
243298bea7Sopenharmony_ciconst char *g_devaccesstokenid = "/dev/access_token_id";
253298bea7Sopenharmony_ci
263298bea7Sopenharmony_ciint GetTokenid(unsigned long long *token)
273298bea7Sopenharmony_ci{
283298bea7Sopenharmony_ci    int fd = open(g_devaccesstokenid, O_RDWR);
293298bea7Sopenharmony_ci    if (fd < 0) {
303298bea7Sopenharmony_ci        return -1;
313298bea7Sopenharmony_ci    }
323298bea7Sopenharmony_ci    int ret = ioctl(fd, ACCESS_TOKENID_GET_TOKENID, token);
333298bea7Sopenharmony_ci    if (ret != 0) {
343298bea7Sopenharmony_ci        close(fd);
353298bea7Sopenharmony_ci        return -1;
363298bea7Sopenharmony_ci    }
373298bea7Sopenharmony_ci    close(fd);
383298bea7Sopenharmony_ci    return 0;
393298bea7Sopenharmony_ci}
403298bea7Sopenharmony_ci
413298bea7Sopenharmony_ciint SetTokenid(unsigned long long *token)
423298bea7Sopenharmony_ci{
433298bea7Sopenharmony_ci    int fd = open(g_devaccesstokenid, O_RDWR);
443298bea7Sopenharmony_ci    if (fd < 0) {
453298bea7Sopenharmony_ci        return -1;
463298bea7Sopenharmony_ci    }
473298bea7Sopenharmony_ci    int ret = ioctl(fd, ACCESS_TOKENID_SET_TOKENID, token);
483298bea7Sopenharmony_ci    if (ret != 0) {
493298bea7Sopenharmony_ci        close(fd);
503298bea7Sopenharmony_ci        return -1;
513298bea7Sopenharmony_ci    }
523298bea7Sopenharmony_ci    close(fd);
533298bea7Sopenharmony_ci    return 0;
543298bea7Sopenharmony_ci}
553298bea7Sopenharmony_ci
563298bea7Sopenharmony_civoid SetUidAndGrp()
573298bea7Sopenharmony_ci{
583298bea7Sopenharmony_ci    int ret = 0;
593298bea7Sopenharmony_ci    size_t groupListSize = LIST_NUM_2;
603298bea7Sopenharmony_ci    gid_t groupList[LIST_NUM_2] = {ACCESS_TOKEN_GRPID, TEST_VALUE};
613298bea7Sopenharmony_ci
623298bea7Sopenharmony_ci    ret = setgroups(groupListSize, groupList);
633298bea7Sopenharmony_ci    if (ret != 0) {
643298bea7Sopenharmony_ci        return;
653298bea7Sopenharmony_ci    }
663298bea7Sopenharmony_ci
673298bea7Sopenharmony_ci    ret = setuid(ACCESS_TOKEN_UID);
683298bea7Sopenharmony_ci    if (ret != 0) {
693298bea7Sopenharmony_ci        printf("SetUidAndGrp setuid error %d \n", ret);
703298bea7Sopenharmony_ci    }
713298bea7Sopenharmony_ci
723298bea7Sopenharmony_ci    return;
733298bea7Sopenharmony_ci}
743298bea7Sopenharmony_ci
753298bea7Sopenharmony_civoid SetUidAndGrpOther()
763298bea7Sopenharmony_ci{
773298bea7Sopenharmony_ci    int ret = 0;
783298bea7Sopenharmony_ci    size_t groupListSize = LIST_NUM_1;
793298bea7Sopenharmony_ci    gid_t groupList[LIST_NUM_1] = {ACCESS_TOKEN_OTHER_GRPID};
803298bea7Sopenharmony_ci
813298bea7Sopenharmony_ci    ret = setgroups(groupListSize, groupList);
823298bea7Sopenharmony_ci    if (ret != 0) {
833298bea7Sopenharmony_ci        return;
843298bea7Sopenharmony_ci    }
853298bea7Sopenharmony_ci
863298bea7Sopenharmony_ci    ret = setuid(ACCESS_TOKEN_OTHER_UID);
873298bea7Sopenharmony_ci    if (ret != 0) {
883298bea7Sopenharmony_ci        printf("SetUidAndGrp setuid error %d \n", ret);
893298bea7Sopenharmony_ci    }
903298bea7Sopenharmony_ci
913298bea7Sopenharmony_ci    return;
923298bea7Sopenharmony_ci}
933298bea7Sopenharmony_ci
943298bea7Sopenharmony_civoid SetRandTokenAndCheck(const unsigned long long *dataToken)
953298bea7Sopenharmony_ci{
963298bea7Sopenharmony_ci    pid_t pid = getpid();
973298bea7Sopenharmony_ci    pid_t tid = syscall(__NR_gettid);
983298bea7Sopenharmony_ci    unsigned long long token = INVAL_TOKEN;
993298bea7Sopenharmony_ci    unsigned long long tokenSet = *dataToken;
1003298bea7Sopenharmony_ci
1013298bea7Sopenharmony_ci    SetTokenid(&tokenSet);
1023298bea7Sopenharmony_ci    GetTokenid(&token);
1033298bea7Sopenharmony_ci
1043298bea7Sopenharmony_ci    if (token != tokenSet) {
1053298bea7Sopenharmony_ci        printf("pid:%d tid:%d token test failed, token:%llu tokenSet:%llu\n",
1063298bea7Sopenharmony_ci               pid, tid, token, tokenSet);
1073298bea7Sopenharmony_ci    } else {
1083298bea7Sopenharmony_ci        printf("pid:%d tid:%d token test succeed, token:%llu tokenSet:%llu\n",
1093298bea7Sopenharmony_ci               pid, tid, token, tokenSet);
1103298bea7Sopenharmony_ci    }
1113298bea7Sopenharmony_ci
1123298bea7Sopenharmony_ci    sleep(WAIT_FOR_SHELL_OP_TIME);
1133298bea7Sopenharmony_ci
1143298bea7Sopenharmony_ci    GetTokenid(&token);
1153298bea7Sopenharmony_ci    if (token != tokenSet) {
1163298bea7Sopenharmony_ci        printf("pid:%d tid:%d token test failed, token:%llu tokenSet:%llu\n",
1173298bea7Sopenharmony_ci               pid, tid, token, tokenSet);
1183298bea7Sopenharmony_ci    } else {
1193298bea7Sopenharmony_ci        printf("pid:%d tid:%d token test succeed, token:%llu tokenSet:%llu\n",
1203298bea7Sopenharmony_ci               pid, tid, token, tokenSet);
1213298bea7Sopenharmony_ci    }
1223298bea7Sopenharmony_ci    return;
1233298bea7Sopenharmony_ci}
1243298bea7Sopenharmony_ci
1253298bea7Sopenharmony_civoid *TokenTest(void *dataToken)
1263298bea7Sopenharmony_ci{
1273298bea7Sopenharmony_ci    SetRandTokenAndCheck(static_cast<unsigned long long *>(dataToken));
1283298bea7Sopenharmony_ci    return nullptr;
1293298bea7Sopenharmony_ci}
1303298bea7Sopenharmony_ci
1313298bea7Sopenharmony_civoid ThreadTest(void *dataToken)
1323298bea7Sopenharmony_ci{
1333298bea7Sopenharmony_ci    pthread_t tid1;
1343298bea7Sopenharmony_ci    pthread_t tid2;
1353298bea7Sopenharmony_ci    pthread_t tid3;
1363298bea7Sopenharmony_ci    int ret = 0;
1373298bea7Sopenharmony_ci
1383298bea7Sopenharmony_ci    ret = pthread_create(&tid1, nullptr, TokenTest, dataToken);
1393298bea7Sopenharmony_ci    if (ret != 0) {
1403298bea7Sopenharmony_ci        return;
1413298bea7Sopenharmony_ci    }
1423298bea7Sopenharmony_ci
1433298bea7Sopenharmony_ci    ret = pthread_create(&tid2, nullptr, TokenTest, dataToken);
1443298bea7Sopenharmony_ci    if (ret != 0) {
1453298bea7Sopenharmony_ci        return;
1463298bea7Sopenharmony_ci    }
1473298bea7Sopenharmony_ci
1483298bea7Sopenharmony_ci    ret = pthread_create(&tid3, nullptr, TokenTest, dataToken);
1493298bea7Sopenharmony_ci    if (ret != 0) {
1503298bea7Sopenharmony_ci        return;
1513298bea7Sopenharmony_ci    }
1523298bea7Sopenharmony_ci
1533298bea7Sopenharmony_ci    pthread_join(tid1, nullptr);
1543298bea7Sopenharmony_ci    pthread_join(tid2, nullptr);
1553298bea7Sopenharmony_ci    pthread_join(tid3, nullptr);
1563298bea7Sopenharmony_ci
1573298bea7Sopenharmony_ci    return;
1583298bea7Sopenharmony_ci}
1593298bea7Sopenharmony_ci
1603298bea7Sopenharmony_ciint AccessTokenidThreadTest(uint8_t *dataToken)
1613298bea7Sopenharmony_ci{
1623298bea7Sopenharmony_ci    TokenTest(static_cast<void *>(dataToken));
1633298bea7Sopenharmony_ci    ThreadTest(static_cast<void *>(dataToken));
1643298bea7Sopenharmony_ci    return 0;
1653298bea7Sopenharmony_ci}
1663298bea7Sopenharmony_ci
1673298bea7Sopenharmony_ciint AccessTokenidGrpTest(uint8_t *dataToken)
1683298bea7Sopenharmony_ci{
1693298bea7Sopenharmony_ci    SetUidAndGrp();
1703298bea7Sopenharmony_ci    TokenTest(static_cast<void *>(dataToken));
1713298bea7Sopenharmony_ci    ThreadTest(static_cast<void *>(dataToken));
1723298bea7Sopenharmony_ci    return 0;
1733298bea7Sopenharmony_ci}
1743298bea7Sopenharmony_ci
1753298bea7Sopenharmony_ciint AccessTokenidGrpTestOther(uint8_t *dataToken)
1763298bea7Sopenharmony_ci{
1773298bea7Sopenharmony_ci    SetUidAndGrpOther();
1783298bea7Sopenharmony_ci    TokenTest(static_cast<void *>(dataToken));
1793298bea7Sopenharmony_ci    ThreadTest(static_cast<void *>(dataToken));
1803298bea7Sopenharmony_ci    return 0;
1813298bea7Sopenharmony_ci}
1823298bea7Sopenharmony_ci
1833298bea7Sopenharmony_ciint GetfTokenid(unsigned long long *ftoken)
1843298bea7Sopenharmony_ci{
1853298bea7Sopenharmony_ci    int fd = open(g_devaccesstokenid, O_RDWR);
1863298bea7Sopenharmony_ci    if (fd < 0) {
1873298bea7Sopenharmony_ci        return -1;
1883298bea7Sopenharmony_ci    }
1893298bea7Sopenharmony_ci
1903298bea7Sopenharmony_ci    int ret = ioctl(fd, ACCESS_TOKENID_GET_FTOKENID, ftoken);
1913298bea7Sopenharmony_ci    if (ret != 0) {
1923298bea7Sopenharmony_ci        close(fd);
1933298bea7Sopenharmony_ci        return -1;
1943298bea7Sopenharmony_ci    }
1953298bea7Sopenharmony_ci
1963298bea7Sopenharmony_ci    close(fd);
1973298bea7Sopenharmony_ci    return 0;
1983298bea7Sopenharmony_ci}
1993298bea7Sopenharmony_ci
2003298bea7Sopenharmony_ciint SetfTokenid(unsigned long long *ftoken)
2013298bea7Sopenharmony_ci{
2023298bea7Sopenharmony_ci    int fd = open(g_devaccesstokenid, O_RDWR);
2033298bea7Sopenharmony_ci    if (fd < 0) {
2043298bea7Sopenharmony_ci        return -1;
2053298bea7Sopenharmony_ci    }
2063298bea7Sopenharmony_ci
2073298bea7Sopenharmony_ci    int ret = ioctl(fd, ACCESS_TOKENID_SET_FTOKENID, ftoken);
2083298bea7Sopenharmony_ci    if (ret != 0) {
2093298bea7Sopenharmony_ci        close(fd);
2103298bea7Sopenharmony_ci        return -1;
2113298bea7Sopenharmony_ci    }
2123298bea7Sopenharmony_ci
2133298bea7Sopenharmony_ci    close(fd);
2143298bea7Sopenharmony_ci    return 0;
2153298bea7Sopenharmony_ci}
2163298bea7Sopenharmony_ci
2173298bea7Sopenharmony_civoid SetRandfTokenAndCheck(const unsigned long long *dataFtoken)
2183298bea7Sopenharmony_ci{
2193298bea7Sopenharmony_ci    pid_t pid = getpid();
2203298bea7Sopenharmony_ci    pid_t tid = syscall(__NR_gettid);
2213298bea7Sopenharmony_ci    unsigned long long ftoken = INVAL_TOKEN;
2223298bea7Sopenharmony_ci    unsigned long long ftokenSet = *dataFtoken;
2233298bea7Sopenharmony_ci
2243298bea7Sopenharmony_ci    SetfTokenid(&ftokenSet);
2253298bea7Sopenharmony_ci    GetfTokenid(&ftoken);
2263298bea7Sopenharmony_ci
2273298bea7Sopenharmony_ci    if (ftoken != ftokenSet) {
2283298bea7Sopenharmony_ci        printf("pid:%d tid:%d ftoken test failed, ftoken:%llu ftokenSet:%llu\n",
2293298bea7Sopenharmony_ci               pid, tid, ftoken, ftokenSet);
2303298bea7Sopenharmony_ci    } else {
2313298bea7Sopenharmony_ci        printf("pid:%d tid:%d ftoken test succeed, ftoken:%llu ftokenSet:%llu\n",
2323298bea7Sopenharmony_ci               pid, tid, ftoken, ftokenSet);
2333298bea7Sopenharmony_ci    }
2343298bea7Sopenharmony_ci
2353298bea7Sopenharmony_ci    sleep(WAIT_FOR_SHELL_OP_TIME);
2363298bea7Sopenharmony_ci
2373298bea7Sopenharmony_ci    GetfTokenid(&ftoken);
2383298bea7Sopenharmony_ci    if (ftoken != ftokenSet) {
2393298bea7Sopenharmony_ci        printf("pid:%d tid:%d ftoken test failed, ftoken:%llu ftokenSet:%llu\n",
2403298bea7Sopenharmony_ci               pid, tid, ftoken, ftokenSet);
2413298bea7Sopenharmony_ci    } else {
2423298bea7Sopenharmony_ci        printf("pid:%d tid:%d ftoken test succeed, ftoken:%llu ftokenSet:%llu\n",
2433298bea7Sopenharmony_ci               pid, tid, ftoken, ftokenSet);
2443298bea7Sopenharmony_ci    }
2453298bea7Sopenharmony_ci    return;
2463298bea7Sopenharmony_ci}
2473298bea7Sopenharmony_ci
2483298bea7Sopenharmony_civoid *FTokenTest(void *dataFtoken)
2493298bea7Sopenharmony_ci{
2503298bea7Sopenharmony_ci    SetRandfTokenAndCheck(static_cast<unsigned long long *>(dataFtoken));
2513298bea7Sopenharmony_ci    return nullptr;
2523298bea7Sopenharmony_ci}
2533298bea7Sopenharmony_ci
2543298bea7Sopenharmony_ciint AccessfTokenidThreadTest(uint8_t *dataFtoken)
2553298bea7Sopenharmony_ci{
2563298bea7Sopenharmony_ci    FTokenTest(static_cast<void *>(dataFtoken));
2573298bea7Sopenharmony_ci    ThreadTest(static_cast<void *>(dataFtoken));
2583298bea7Sopenharmony_ci    return 0;
2593298bea7Sopenharmony_ci}
2603298bea7Sopenharmony_ci
2613298bea7Sopenharmony_ciint AccessfTokenidGrpTest(uint8_t *dataFtoken)
2623298bea7Sopenharmony_ci{
2633298bea7Sopenharmony_ci    SetUidAndGrp();
2643298bea7Sopenharmony_ci    FTokenTest(static_cast<void *>(dataFtoken));
2653298bea7Sopenharmony_ci    ThreadTest(static_cast<void *>(dataFtoken));
2663298bea7Sopenharmony_ci    return 0;
2673298bea7Sopenharmony_ci}
2683298bea7Sopenharmony_ci
2693298bea7Sopenharmony_ciint AccessfTokenidGrpTestOther(uint8_t *dataFtoken)
2703298bea7Sopenharmony_ci{
2713298bea7Sopenharmony_ci    SetUidAndGrpOther();
2723298bea7Sopenharmony_ci    FTokenTest(static_cast<void *>(dataFtoken));
2733298bea7Sopenharmony_ci    ThreadTest(static_cast<void *>(dataFtoken));
2743298bea7Sopenharmony_ci    return 0;
2753298bea7Sopenharmony_ci}
2763298bea7Sopenharmony_ci
2773298bea7Sopenharmony_cibool SetfTokenidCmdFuzzTest(const uint8_t *data, size_t size)
2783298bea7Sopenharmony_ci{
2793298bea7Sopenharmony_ci    bool ret = false;
2803298bea7Sopenharmony_ci    if ((data == nullptr) || (size < sizeof(unsigned long long))) {
2813298bea7Sopenharmony_ci        return ret;
2823298bea7Sopenharmony_ci    } else {
2833298bea7Sopenharmony_ci        unsigned long long tokenId = *(reinterpret_cast<const unsigned long long *>(data));
2843298bea7Sopenharmony_ci        ret = SetfTokenid(&tokenId);
2853298bea7Sopenharmony_ci    }
2863298bea7Sopenharmony_ci    return ret;
2873298bea7Sopenharmony_ci}
2883298bea7Sopenharmony_ci
2893298bea7Sopenharmony_cibool GetfTokenidCmdFuzzTest(const uint8_t *data, size_t size)
2903298bea7Sopenharmony_ci{
2913298bea7Sopenharmony_ci    bool ret = false;
2923298bea7Sopenharmony_ci    if ((data == nullptr) || (size < sizeof(unsigned long long))) {
2933298bea7Sopenharmony_ci        return ret;
2943298bea7Sopenharmony_ci    } else {
2953298bea7Sopenharmony_ci        unsigned long long tokenId = *(reinterpret_cast<const unsigned long long *>(data));
2963298bea7Sopenharmony_ci        ret = GetfTokenid(&tokenId);
2973298bea7Sopenharmony_ci    }
2983298bea7Sopenharmony_ci    return ret;
2993298bea7Sopenharmony_ci}
3003298bea7Sopenharmony_ci
3013298bea7Sopenharmony_cibool GetTokenidCmdFuzzTest(const uint8_t *data, size_t size)
3023298bea7Sopenharmony_ci{
3033298bea7Sopenharmony_ci    bool ret = false;
3043298bea7Sopenharmony_ci    if ((data == nullptr) || (size < sizeof(unsigned long long))) {
3053298bea7Sopenharmony_ci        return ret;
3063298bea7Sopenharmony_ci    } else {
3073298bea7Sopenharmony_ci        unsigned long long tokenId = *(reinterpret_cast<const unsigned long long *>(data));
3083298bea7Sopenharmony_ci        ret = GetTokenid(&tokenId);
3093298bea7Sopenharmony_ci    }
3103298bea7Sopenharmony_ci    return ret;
3113298bea7Sopenharmony_ci}
3123298bea7Sopenharmony_ci
3133298bea7Sopenharmony_cibool SetTokenidCmdFuzzTest(const uint8_t *data, size_t size)
3143298bea7Sopenharmony_ci{
3153298bea7Sopenharmony_ci    bool ret = false;
3163298bea7Sopenharmony_ci    if ((data == nullptr) || (size < sizeof(unsigned long long))) {
3173298bea7Sopenharmony_ci        return ret;
3183298bea7Sopenharmony_ci    } else {
3193298bea7Sopenharmony_ci        unsigned long long tokenId = *(reinterpret_cast<const unsigned long long *>(data));
3203298bea7Sopenharmony_ci        ret = SetTokenid(&tokenId);
3213298bea7Sopenharmony_ci    }
3223298bea7Sopenharmony_ci    return ret;
3233298bea7Sopenharmony_ci}
3243298bea7Sopenharmony_ci} // namespace AccessToken
3253298bea7Sopenharmony_ci} // namespace Kernel
3263298bea7Sopenharmony_ci} // namespace OHOS
327