1/*
2 * Copyright (c) 2022 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 "abilityconnectmanager_fuzzer.h"
17
18#include <cstddef>
19#include <cstdint>
20
21#define private public
22#include "ability_connect_manager.h"
23#undef private
24
25#include "ability_connect_callback_interface.h"
26#include "ability_connect_callback_stub.h"
27
28using namespace OHOS::AAFwk;
29using namespace OHOS::AppExecFwk;
30
31namespace OHOS {
32namespace {
33constexpr int INPUT_ZERO = 0;
34constexpr int INPUT_ONE = 1;
35constexpr int INPUT_THREE = 3;
36constexpr size_t FOO_MAX_LEN = 1024;
37constexpr uint8_t ENABLE = 2;
38constexpr size_t U32_AT_SIZE = 4;
39constexpr size_t OFFSET_ZERO = 24;
40constexpr size_t OFFSET_ONE = 16;
41constexpr size_t OFFSET_TWO = 8;
42class AbilityConnectCallback : public AbilityConnectionStub {
43public:
44    AbilityConnectCallback() = default;
45    virtual ~AbilityConnectCallback() = default;
46    void OnAbilityConnectDone(
47        const AppExecFwk::ElementName& element, const sptr<IRemoteObject>& remoteObject, int resultCode) override
48    {}
49    void OnAbilityDisconnectDone(const AppExecFwk::ElementName& element, int resultCode) override
50    {}
51};
52}
53
54uint32_t GetU32Data(const char* ptr)
55{
56    // convert fuzz input data to an integer
57    return (ptr[INPUT_ZERO] << OFFSET_ZERO) | (ptr[INPUT_ONE] << OFFSET_ONE) | (ptr[ENABLE] << OFFSET_TWO) |
58        ptr[INPUT_THREE];
59}
60
61std::shared_ptr<AbilityRecord> GetFuzzAbilityRecord()
62{
63    sptr<Token> token = nullptr;
64    AbilityRequest abilityRequest;
65    abilityRequest.appInfo.bundleName = "com.example.fuzzTest";
66    abilityRequest.abilityInfo.name = "MainAbility";
67    abilityRequest.abilityInfo.type = AbilityType::DATA;
68    std::shared_ptr<AbilityRecord> abilityRecord = AbilityRecord::CreateAbilityRecord(abilityRequest);
69    if (!abilityRecord) {
70        return nullptr;
71    }
72    return abilityRecord;
73}
74
75sptr<Token> GetFuzzAbilityToken()
76{
77    sptr<Token> token = nullptr;
78    std::shared_ptr<AbilityRecord> abilityRecord = GetFuzzAbilityRecord();
79    if (abilityRecord) {
80        token = abilityRecord->GetToken();
81    }
82    return token;
83}
84
85bool DoSomethingInterestingWithMyAPI(const char* data, size_t size)
86{
87    int intParam = static_cast<int>(GetU32Data(data));
88    std::shared_ptr<AbilityConnectManager> abilityConnectManager = std::make_shared<AbilityConnectManager>(intParam);
89    AbilityRequest abilityRequest;
90    abilityConnectManager->StartAbility(abilityRequest);
91    sptr<IRemoteObject> token = GetFuzzAbilityToken();
92    abilityConnectManager->TerminateAbility(token);
93    abilityConnectManager->StopServiceAbility(abilityRequest);
94    abilityConnectManager->StartAbilityLocked(abilityRequest);
95    abilityConnectManager->TerminateAbilityLocked(token);
96    abilityConnectManager->StopServiceAbilityLocked(abilityRequest);
97    bool boolParam = *data % ENABLE;
98    std::shared_ptr<AbilityRecord> targetService = GetFuzzAbilityRecord();
99    abilityConnectManager->GetOrCreateServiceRecord(abilityRequest, boolParam, targetService, boolParam);
100    const sptr<IAbilityConnection> connect = new AbilityConnectCallback();
101    std::list<std::shared_ptr<ConnectionRecord>> connectRecordList;
102    abilityConnectManager->GetConnectRecordListFromMap(connect, connectRecordList);
103    sptr<IRemoteObject> callerToken = GetFuzzAbilityToken();
104    abilityConnectManager->ConnectAbilityLocked(abilityRequest, connect, callerToken);
105    abilityConnectManager->DisconnectAbilityLocked(connect);
106    sptr<IAbilityScheduler> scheduler = nullptr;
107    abilityConnectManager->AttachAbilityThreadLocked(scheduler, token);
108    AppInfo appInfo;
109    abilityConnectManager->OnAppStateChanged(appInfo);
110    abilityConnectManager->AbilityTransitionDone(token, intParam);
111    sptr<IRemoteObject> remoteObject = nullptr;
112    abilityConnectManager->ScheduleConnectAbilityDoneLocked(token, remoteObject);
113    abilityConnectManager->ScheduleDisconnectAbilityDoneLocked(token);
114    abilityConnectManager->ScheduleCommandAbilityDoneLocked(token);
115    std::shared_ptr<AbilityRecord> abilityRecord = GetFuzzAbilityRecord();
116    abilityConnectManager->CompleteCommandAbility(abilityRecord);
117    std::string stringParam(data, size);
118    abilityConnectManager->GetServiceRecordByElementName(stringParam);
119    abilityConnectManager->GetExtensionByTokenFromServiceMap(token);
120    sptr<IAbilityConnection> callback = new AbilityConnectCallback();
121    abilityConnectManager->GetConnectRecordListByCallback(callback);
122    int64_t int64Param = static_cast<int64_t>(GetU32Data(data));
123    abilityConnectManager->GetAbilityRecordById(int64Param);
124    abilityConnectManager->LoadAbility(abilityRecord);
125    uint32_t uint32Param = GetU32Data(data);
126    abilityConnectManager->PostTimeOutTask(abilityRecord, uint32Param);
127    abilityConnectManager->HandleStartTimeoutTask(abilityRecord);
128    abilityConnectManager->HandleCommandTimeoutTask(abilityRecord);
129    abilityConnectManager->HandleStopTimeoutTask(abilityRecord);
130    AbilityConnectManager::ConnectListType connectlist;
131    abilityConnectManager->HandleTerminateDisconnectTask(connectlist);
132    abilityConnectManager->DispatchInactive(abilityRecord, intParam);
133    abilityConnectManager->DispatchTerminate(abilityRecord);
134    abilityConnectManager->ConnectAbility(abilityRecord);
135    abilityConnectManager->CommandAbility(abilityRecord);
136    abilityConnectManager->TerminateDone(abilityRecord);
137    abilityConnectManager->IsAbilityConnected(abilityRecord, connectRecordList);
138    std::shared_ptr<ConnectionRecord> connection;
139    abilityConnectManager->RemoveConnectionRecordFromMap(connection);
140    abilityConnectManager->RemoveServiceAbility(abilityRecord);
141    abilityConnectManager->AddConnectDeathRecipient(connect);
142    abilityConnectManager->RemoveConnectDeathRecipient(connect);
143    sptr<IRemoteObject> connectRemoteObject = GetFuzzAbilityToken();
144    wptr<IRemoteObject> remote = connectRemoteObject;
145    abilityConnectManager->OnCallBackDied(remote);
146    abilityConnectManager->HandleCallBackDiedTask(connectRemoteObject);
147    int int32Param = static_cast<int32_t>(GetU32Data(data));
148    abilityConnectManager->OnAbilityDied(abilityRecord, int32Param);
149    abilityConnectManager->OnTimeOut(uint32Param, int64Param);
150    std::shared_ptr<AbilityRecord> ability = GetFuzzAbilityRecord();
151    abilityConnectManager->HandleInactiveTimeout(ability);
152    abilityConnectManager->IsAbilityNeedKeepAlive(abilityRecord);
153    abilityConnectManager->HandleAbilityDiedTask(abilityRecord, int32Param);
154    std::vector<std::string> info;
155    abilityConnectManager->DumpState(info, boolParam, stringParam);
156    abilityConnectManager->DumpStateByUri(info, boolParam, stringParam, info);
157    std::vector<ExtensionRunningInfo> extensionRunningInfo;
158    abilityConnectManager->GetExtensionRunningInfos(intParam, extensionRunningInfo, int32Param, boolParam);
159    std::vector<AbilityRunningInfo> abilityRunningInfo;
160    abilityConnectManager->GetAbilityRunningInfos(abilityRunningInfo, boolParam);
161    abilityConnectManager->GetExtensionRunningInfo(abilityRecord, int32Param, extensionRunningInfo);
162    abilityConnectManager->PauseExtensions();
163    return true;
164}
165}
166
167/* Fuzzer entry point */
168extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
169{
170    /* Run your code on data */
171    if (data == nullptr) {
172        std::cout << "invalid data" << std::endl;
173        return 0;
174    }
175
176    /* Validate the length of size */
177    if (size > OHOS::FOO_MAX_LEN || size < OHOS::U32_AT_SIZE) {
178        return 0;
179    }
180
181    char* ch = (char*)malloc(size + 1);
182    if (ch == nullptr) {
183        std::cout << "malloc failed." << std::endl;
184        return 0;
185    }
186
187    (void)memset_s(ch, size + 1, 0x00, size + 1);
188    if (memcpy_s(ch, size, data, size) != EOK) {
189        std::cout << "copy failed." << std::endl;
190        free(ch);
191        ch = nullptr;
192        return 0;
193    }
194
195    OHOS::DoSomethingInterestingWithMyAPI(ch, size);
196    free(ch);
197    ch = nullptr;
198    return 0;
199}
200
201