1 /*
2  * Copyright (c) 2023 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 "getpermissionsstatusstub_fuzzer.h"
17 
18 #include <sys/types.h>
19 #include <unistd.h>
20 #include <string>
21 #include <thread>
22 #include <vector>
23 #undef private
24 #include "access_token.h"
25 #include "accesstoken_kit.h"
26 #include "accesstoken_manager_service.h"
27 #include "i_accesstoken_manager.h"
28 #include "nativetoken_kit.h"
29 #include "securec.h"
30 #include "token_setproc.h"
31 
32 using namespace std;
33 using namespace OHOS;
34 using namespace OHOS::Security::AccessToken;
35 const int CONSTANTS_NUMBER_TWO = 2;
36 static const int32_t ROOT_UID = 0;
37 
38 namespace OHOS {
39 const uint8_t *g_baseFuzzData = nullptr;
40 size_t g_baseFuzzSize = 0;
41 size_t g_baseFuzzPos = 0;
GetNativeToken()42     void GetNativeToken()
43     {
44         uint64_t tokenId;
45         const char **perms = new const char *[1];
46         perms[0] = "ohos.permission.GET_SENSITIVE_PERMISSIONS"; // 3 means the third permission
47 
48         NativeTokenInfoParams infoInstance = {
49             .dcapsNum = 0,
50             .permsNum = 1,
51             .aclsNum = 0,
52             .dcaps = nullptr,
53             .perms = perms,
54             .acls = nullptr,
55             .processName = "getpermissionsstatusstub_fuzzer_test",
56             .aplStr = "system_core",
57         };
58 
59         tokenId = GetAccessTokenId(&infoInstance);
60         SetSelfTokenID(tokenId);
61         AccessTokenKit::ReloadNativeTokenInfo();
62         delete[] perms;
63     }
64 
65     /*
66     * describe: get data from outside untrusted data(g_data) which size is according to sizeof(T)
67     * tips: only support basic type
68     */
GetData()69     template<class T> T GetData()
70     {
71         T object {};
72         size_t objectSize = sizeof(object);
73         if (g_baseFuzzData == nullptr || objectSize > g_baseFuzzSize - g_baseFuzzPos) {
74             return object;
75         }
76         errno_t ret = memcpy_s(&object, objectSize, g_baseFuzzData + g_baseFuzzPos, objectSize);
77         if (ret != EOK) {
78             return {};
79         }
80         g_baseFuzzPos += objectSize;
81         return object;
82     }
83 
GetStringFromData(int strlen)84     std::string GetStringFromData(int strlen)
85     {
86         char cstr[strlen];
87         cstr[strlen - 1] = '\0';
88         for (int i = 0; i < strlen - 1; i++) {
89             cstr[i] = GetData<char>();
90         }
91         std::string str(cstr);
92         return str;
93     }
94 
GetPermissionsStatusStubFuzzTest(const uint8_t * data,size_t size)95     bool GetPermissionsStatusStubFuzzTest(const uint8_t* data, size_t size)
96     {
97         if ((data == nullptr) || (size == 0)) {
98             return false;
99         }
100         int32_t result = RET_SUCCESS;
101         g_baseFuzzData = data;
102         g_baseFuzzSize = size;
103         g_baseFuzzPos = 0;
104         if (size > sizeof(uint32_t) + sizeof(std::string)) {
105             AccessTokenID tokenId = static_cast<AccessTokenID>(GetData<uint32_t>());
106             std::string testPerName = GetStringFromData(int(size));
107             PermissionListState perm = {
108             .permissionName = testPerName,
109             .state = SETTING_OPER,
110             };
111             PermissionListStateParcel permParcel;
112             permParcel.permsState = perm;
113             MessageParcel datas;
114             datas.WriteInterfaceToken(IAccessTokenManager::GetDescriptor());
115             if (!datas.WriteUint32(tokenId)) {
116                 return false;
117             }
118             if (!datas.WriteParcelable(&permParcel)) {
119                 return false;
120             }
121 
122             uint32_t code = static_cast<uint32_t>(
123                 AccessTokenInterfaceCode::GET_PERMISSIONS_STATUS);
124             MessageParcel reply;
125             MessageOption option;
126             bool enable = ((size % CONSTANTS_NUMBER_TWO) == 0);
127             if (enable) {
128                 setuid(CONSTANTS_NUMBER_TWO);
129             }
130             DelayedSingleton<AccessTokenManagerService>::GetInstance()->OnRemoteRequest(code, datas, reply, option);
131             setuid(ROOT_UID);
132         }
133         return result == RET_SUCCESS;
134     }
135 }
136 
137 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)138 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
139 {
140     /* Run your code on data */
141     OHOS::GetNativeToken();
142     OHOS::GetPermissionsStatusStubFuzzTest(data, size);
143     return 0;
144 }
145 
146