1 /*
2 * Copyright (c) 2023-2025 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 "subscribeosaccountstub_fuzzer.h"
17 #include <string>
18 #include <thread>
19 #include <vector>
20
21 #include "access_token.h"
22 #include "access_token_error.h"
23 #include "accesstoken_kit.h"
24 #include "fuzz_data.h"
25 #include "ios_account.h"
26 #include "nativetoken_kit.h"
27 #include "os_account_event_listener.h"
28 #include "os_account_manager_service.h"
29 #include "os_account_subscriber.h"
30 #include "os_account_subscribe_manager.h"
31 #include "token_setproc.h"
32
33 using namespace std;
34 using namespace OHOS;
35 using namespace OHOS::AccountSA;
36 using namespace OHOS::Security::AccessToken;
37
38 class TestOsAccountEventListener : public OsAccountEventListener {
39 public:
40 TestOsAccountEventListener() = default;
41 virtual ~TestOsAccountEventListener() = default;
42
OnAccountsChanged(int32_t id)43 OHOS::ErrCode OnAccountsChanged(int32_t id) override
44 {
45 return OHOS::ERR_OK;
46 }
OnStateChanged(const OsAccountStateParcel & parcel)47 OHOS::ErrCode OnStateChanged(const OsAccountStateParcel &parcel) override
48 {
49 return ERR_OK;
50 }
OnAccountsSwitch(int newId,int oldId)51 OHOS::ErrCode OnAccountsSwitch(int newId, int oldId) override
52 {
53 return OHOS::ERR_OK;
54 }
55 };
56
57 namespace OHOS {
58 const int CONSTANTS_STATE_MAX = 13;
59 const int CONSTANTS_SUBSCRIBE_TYPE_MAX = 13;
60 constexpr uint32_t MAX_STATE_PUBLISH_COUNT = 100;
61 constexpr uint32_t MIN_STATE_PUBLISH_COUNT = 1;
62 constexpr int32_t PERMISSION_COUNT_NUM = 2;
63 constexpr int32_t FIRST_PARAM_INDEX = 0;
64 constexpr int32_t SECOND_PARAM_INDEX = 1;
65 const std::u16string IOS_ACCOUNT_DESCRIPTOR = u"ohos.accountfwk.IOsAccount";
SubscribeOsAccountStubFuzzTest(const uint8_t * data,size_t size)66 bool SubscribeOsAccountStubFuzzTest(const uint8_t *data, size_t size)
67 {
68 if ((data == nullptr) || (size == 0)) {
69 return false;
70 }
71
72 MessageParcel datas;
73 datas.WriteInterfaceToken(IOS_ACCOUNT_DESCRIPTOR);
74 FuzzData fuzzData(data, size);
75
76 auto useOsAccountSubscribeInfo = fuzzData.GenerateBool();
77 if (useOsAccountSubscribeInfo) {
78 OsAccountSubscribeInfo subscribeInfo;
79 subscribeInfo.SetName(fuzzData.GenerateString());
80 int32_t subscribeTypeValue = (fuzzData.GetData<int32_t>() % CONSTANTS_SUBSCRIBE_TYPE_MAX) - 1;
81 OS_ACCOUNT_SUBSCRIBE_TYPE testType = static_cast<OS_ACCOUNT_SUBSCRIBE_TYPE>(subscribeTypeValue);
82 subscribeInfo.SetOsAccountSubscribeType(testType);
83 if (!datas.WriteParcelable(&subscribeInfo)) {
84 return false;
85 }
86 }
87 auto useOsAccountEventListener = fuzzData.GenerateBool();
88 if (useOsAccountEventListener) {
89 sptr<OsAccountEventListener> listener = new (std::nothrow) OsAccountEventListener();
90 if (listener == nullptr) {
91 return false;
92 }
93 sptr<IRemoteObject> osAccountEventListener = listener->AsObject();
94 if (!datas.WriteRemoteObject(osAccountEventListener)) {
95 return false;
96 }
97 }
98
99 MessageParcel reply;
100 MessageOption option;
101
102 auto osAccountManagerService_ = std::make_shared<OsAccountManagerService>();
103
104 osAccountManagerService_ ->OnRemoteRequest(
105 static_cast<int32_t>(IOsAccountIpcCode::COMMAND_SUBSCRIBE_OS_ACCOUNT), datas, reply, option);
106
107 return true;
108 }
109
UnsubscribeOsAccountStubFuzzTest(const uint8_t * data,size_t size)110 bool UnsubscribeOsAccountStubFuzzTest(const uint8_t *data, size_t size)
111 {
112 if ((data == nullptr) || (size == 0)) {
113 return false;
114 }
115
116 MessageParcel datas;
117 datas.WriteInterfaceToken(IOS_ACCOUNT_DESCRIPTOR);
118 FuzzData fuzzData(data, size);
119
120 auto useOsAccountEventListener = fuzzData.GenerateBool();
121 if (useOsAccountEventListener) {
122 sptr<OsAccountEventListener> listener = new (std::nothrow) TestOsAccountEventListener();
123 if (listener == nullptr) {
124 return false;
125 }
126 sptr<IRemoteObject> osAccountEventListener = listener->AsObject();
127 if (!datas.WriteRemoteObject(osAccountEventListener)) {
128 return false;
129 }
130 }
131
132 MessageParcel reply;
133 MessageOption option;
134
135 auto osAccountManagerService_ = std::make_shared<OsAccountManagerService>();
136 osAccountManagerService_->OnRemoteRequest(
137 static_cast<int32_t>(IOsAccountIpcCode::COMMAND_UNSUBSCRIBE_OS_ACCOUNT), datas, reply, option);
138
139 return true;
140 }
141
OsAccountSubscribeFuzzTest(const uint8_t * data,size_t size)142 bool OsAccountSubscribeFuzzTest(const uint8_t *data, size_t size)
143 {
144 if ((data == nullptr) || (size == 0)) {
145 return false;
146 }
147
148 FuzzData fuzzData(data, size);
149
150 auto subscribeInfo = std::make_shared<OsAccountSubscribeInfo>();
151 subscribeInfo->SetName(fuzzData.GenerateString());
152
153 int32_t subscribeTypeValue = (fuzzData.GetData<int32_t>() % CONSTANTS_SUBSCRIBE_TYPE_MAX) - 1;
154 OS_ACCOUNT_SUBSCRIBE_TYPE testType = static_cast<OS_ACCOUNT_SUBSCRIBE_TYPE>(subscribeTypeValue);
155 subscribeInfo->SetOsAccountSubscribeType(testType);
156
157 sptr<OsAccountEventListener> listener = new (std::nothrow) TestOsAccountEventListener();
158 if (listener == nullptr) {
159 return false;
160 }
161 sptr<IRemoteObject> eventListener = listener->AsObject();
162 if (eventListener == nullptr) {
163 return false;
164 }
165
166 OsAccountSubscribeManager::GetInstance().SubscribeOsAccount(subscribeInfo, eventListener);
167
168 uint32_t stateCount = (fuzzData.GetData<uint32_t>() % MAX_STATE_PUBLISH_COUNT) + MIN_STATE_PUBLISH_COUNT;
169
170 for (uint32_t i = 0; i < stateCount; i++) {
171 int32_t stateValue = (fuzzData.GetData<int32_t>() % CONSTANTS_STATE_MAX) - 1;
172 OsAccountState randomState = static_cast<OsAccountState>(stateValue);
173 int32_t randomFromId = fuzzData.GetData<int32_t>();
174 int32_t randomToId = fuzzData.GetData<int32_t>();
175
176 OsAccountSubscribeManager::GetInstance().Publish(randomFromId, randomState, randomToId);
177 }
178
179 OsAccountSubscribeManager::GetInstance().UnsubscribeOsAccount(eventListener);
180 return true;
181 }
182
OsAccountSubscribeWithHandshakeFuzzTest(const uint8_t * data,size_t size)183 bool OsAccountSubscribeWithHandshakeFuzzTest(const uint8_t *data, size_t size)
184 {
185 if ((data == nullptr) || (size == 0)) {
186 return false;
187 }
188
189 FuzzData fuzzData(data, size);
190
191 std::set<OsAccountState> states = { OsAccountState::STOPPING, OsAccountState::CREATED, OsAccountState::SWITCHING,
192 OsAccountState::SWITCHED, OsAccountState::UNLOCKED, OsAccountState::STOPPED, OsAccountState::REMOVED,
193 OsAccountState::LOCKING, OsAccountState::LOCKED};
194 auto subscribeInfo = std::make_shared<OsAccountSubscribeInfo>(states, fuzzData.GetData<bool>());
195 sptr<OsAccountEventListener> listener = new (std::nothrow) TestOsAccountEventListener();
196 if (listener == nullptr) {
197 return false;
198 }
199 sptr<IRemoteObject> eventListener = listener->AsObject();
200 OsAccountSubscribeManager::GetInstance().SubscribeOsAccount(subscribeInfo, eventListener);
201
202 int32_t fromId = fuzzData.GetData<int32_t>();
203 int32_t toId = fuzzData.GetData<int32_t>();
204 OsAccountState targetState = static_cast<OsAccountState>((fuzzData.GetData<int32_t>() % CONSTANTS_STATE_MAX) - 1);
205 OsAccountSubscribeManager::GetInstance().Publish(fromId, targetState, toId);
206 OsAccountSubscribeManager::GetInstance().UnsubscribeOsAccount(eventListener);
207 return true;
208 }
209 } // namespace OHOS
210
NativeTokenGet()211 void NativeTokenGet()
212 {
213 uint64_t tokenId;
214 const char **perms = new const char *[PERMISSION_COUNT_NUM];
215 perms[FIRST_PARAM_INDEX] = "ohos.permission.MANAGE_LOCAL_ACCOUNTS";
216 perms[SECOND_PARAM_INDEX] = "ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS_EXTENSION";
217 NativeTokenInfoParams infoInstance = {
218 .dcapsNum = 0,
219 .permsNum = PERMISSION_COUNT_NUM,
220 .aclsNum = 0,
221 .perms = perms,
222 .acls = nullptr,
223 .aplStr = "system_core",
224 };
225 infoInstance.processName = "RegisterInputer";
226 tokenId = GetAccessTokenId(&infoInstance);
227 SetSelfTokenID(tokenId);
228 AccessTokenKit::ReloadNativeTokenInfo();
229 delete[] perms;
230 }
231
232 /* Fuzzer entry point */
LLVMFuzzerInitialize(int * argc,char *** argv)233 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
234 {
235 NativeTokenGet();
236 return 0;
237 }
238
239 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)240 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
241 {
242 /* Run your code on data */
243 OHOS::SubscribeOsAccountStubFuzzTest(data, size);
244 OHOS::UnsubscribeOsAccountStubFuzzTest(data, size);
245 OHOS::OsAccountSubscribeFuzzTest(data, size);
246 OHOS::OsAccountSubscribeWithHandshakeFuzzTest(data, size);
247 return 0;
248 }
249