1/*
2 * Copyright (c) 2024 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 "connectionstatemanager_fuzzer.h"
17
18#include <cstddef>
19#include <cstdint>
20
21#define private public
22#define protected public
23#include "connection_observer_controller.h"
24#include "connection_record.h"
25#include "connection_state_item.h"
26#include "connection_state_manager.h"
27#undef protected
28#undef private
29
30#include "ability_record.h"
31#include "continuous_task_callback_info.h"
32
33using namespace OHOS::AAFwk;
34using namespace OHOS::AppExecFwk;
35using namespace OHOS::AbilityRuntime;
36
37namespace OHOS {
38namespace {
39constexpr size_t FOO_MAX_LEN = 1024;
40constexpr size_t U32_AT_SIZE = 4;
41constexpr uint8_t ENABLE = 2;
42class MyAbilityConnection : public IAbilityConnection {
43public:
44    MyAbilityConnection() = default;
45    virtual ~MyAbilityConnection() = 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    sptr<IRemoteObject> AsObject() override
52    {
53        return {};
54    }
55};
56class MyAbilityConnectionObserver : public IConnectionObserver {
57public:
58    MyAbilityConnectionObserver() = default;
59    virtual ~MyAbilityConnectionObserver() = default;
60    void OnExtensionConnected(const ConnectionData& data) override
61    {}
62    void OnExtensionDisconnected(const ConnectionData& data) override
63    {}
64#ifdef WITH_DLP
65    void OnDlpAbilityOpened(const DlpStateData& data) override
66    {}
67    void OnDlpAbilityClosed(const DlpStateData& data) override
68    {}
69#endif // WITH_DLP
70    sptr<IRemoteObject> AsObject() override
71    {
72        return {};
73    }
74};
75}
76
77uint32_t GetU32Data(const char* ptr)
78{
79    // convert fuzz input data to an integer
80    return (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3];
81}
82
83std::shared_ptr<AbilityRecord> GetFuzzAbilityRecord()
84{
85    sptr<Token> token = nullptr;
86    AbilityRequest abilityRequest;
87    abilityRequest.appInfo.bundleName = "com.example.fuzzTest";
88    abilityRequest.abilityInfo.name = "MainAbility";
89    abilityRequest.abilityInfo.type = AbilityType::DATA;
90    std::shared_ptr<AbilityRecord> abilityRecord = AbilityRecord::CreateAbilityRecord(abilityRequest);
91    if (!abilityRecord) {
92        return nullptr;
93    }
94    return abilityRecord;
95}
96
97sptr<Token> GetFuzzAbilityToken()
98{
99    sptr<Token> token = nullptr;
100    std::shared_ptr<AbilityRecord> abilityRecord = GetFuzzAbilityRecord();
101    if (abilityRecord) {
102        token = abilityRecord->GetToken();
103    }
104    return token;
105}
106
107bool DoSomethingInterestingWithMyAPI(const char* data, size_t size)
108{
109    bool boolParam = *data % ENABLE;
110    int intParam = static_cast<int>(GetU32Data(data));
111    int32_t int32Param = static_cast<int32_t>(GetU32Data(data));
112    std::string stringParam(data, size);
113    Parcel wantParcel;
114    Want* want = nullptr;
115    if (wantParcel.WriteBuffer(data, size)) {
116        want = Want::Unmarshalling(wantParcel);
117        if (!want) {
118            return false;
119        }
120    }
121    sptr<IRemoteObject> token = GetFuzzAbilityToken();
122    sptr<IAbilityConnection> connect = new MyAbilityConnection();
123    sptr<AbilityRuntime::IConnectionObserver> observer = new MyAbilityConnectionObserver();
124    std::vector<std::string> info;
125    AbilityRuntime::ConnectionData connectionData;
126
127    // fuzz for ConnectionObserverController
128    auto connectionObserverController = std::make_shared<ConnectionObserverController>();
129    connectionObserverController->AddObserver(observer);
130    connectionObserverController->RemoveObserver(observer);
131    connectionObserverController->NotifyExtensionConnected(connectionData);
132    connectionObserverController->NotifyExtensionDisconnected(connectionData);
133#ifdef WITH_DLP
134    AbilityRuntime::DlpStateData dlpStateData;
135    connectionObserverController->NotifyDlpAbilityOpened(dlpStateData);
136    connectionObserverController->NotifyDlpAbilityClosed(dlpStateData);
137#endif // WITH_DLP
138    connectionObserverController->GetObservers();
139    wptr<IRemoteObject> remote;
140    connectionObserverController->HandleRemoteDied(remote);
141    ConnectionObserverController::ObserverDeathRecipient::ObserverDeathHandler handler;
142    std::shared_ptr<ConnectionObserverController::ObserverDeathRecipient> observerDeathRecipient =
143        std::make_shared<ConnectionObserverController::ObserverDeathRecipient>(handler);
144    observerDeathRecipient->OnRemoteDied(remote);
145
146    // fuzz for ConnectionRecord
147    std::shared_ptr<AbilityRecord> targetService = GetFuzzAbilityRecord();
148    auto connectionRecord = std::make_shared<ConnectionRecord>(token, targetService, connect);
149    connectionRecord->CreateConnectionRecord(token, targetService, connect);
150    ConnectionState state = ConnectionState::CONNECTED;
151    connectionRecord->SetConnectState(state);
152    connectionRecord->GetConnectState();
153    connectionRecord->GetToken();
154    connectionRecord->GetAbilityRecord();
155    connectionRecord->GetAbilityConnectCallback();
156    connectionRecord->ClearConnCallBack();
157    connectionRecord->DisconnectAbility();
158    connectionRecord->CompleteConnect(intParam);
159    connectionRecord->CompleteDisconnect(intParam, boolParam);
160    connectionRecord->ScheduleDisconnectAbilityDone();
161    connectionRecord->ScheduleConnectAbilityDone();
162    connectionRecord->DisconnectTimeout();
163    connectionRecord->ConvertConnectionState(state);
164    connectionRecord->Dump(info);
165    connectionRecord->AttachCallerInfo();
166    connectionRecord->GetCallerUid();
167    connectionRecord->GetCallerPid();
168    connectionRecord->GetCallerName();
169    connectionRecord->GetTargetToken();
170    connectionRecord->GetConnection();
171
172    // fuzz for ConnectionRecord
173    auto connectionStateItem = std::make_shared<ConnectionStateItem>(int32Param, int32Param, stringParam);
174    std::shared_ptr<ConnectionRecord> record;
175    connectionStateItem->CreateConnectionStateItem(record);
176    DataAbilityCaller dataCaller;
177    connectionStateItem->CreateConnectionStateItem(dataCaller);
178    connectionStateItem->AddConnection(record, connectionData);
179    connectionStateItem->RemoveConnection(record, connectionData);
180    std::shared_ptr<DataAbilityRecord> dataAbility;
181    connectionStateItem->AddDataAbilityConnection(dataCaller, dataAbility, connectionData);
182    connectionStateItem->RemoveDataAbilityConnection(dataCaller, dataAbility, connectionData);
183    connectionStateItem->HandleDataAbilityDied(token, connectionData);
184    connectionStateItem->IsEmpty();
185    std::vector<AbilityRuntime::ConnectionData> datas;
186    connectionStateItem->GenerateAllConnectionData(datas);
187    std::shared_ptr<ConnectedExtension> connectedExtension;
188    connectionStateItem->GenerateConnectionData(connectedExtension, connectionData);
189    std::shared_ptr<ConnectedDataAbility> connectedDataAbility;
190    connectionStateItem->GenerateConnectionData(connectedDataAbility, connectionData);
191
192    // fuzz for ConnectionStateManager
193    auto connectionStateManager = std::make_shared<ConnectionStateManager>();
194    connectionStateManager->GetProcessNameByPid(int32Param);
195    connectionStateManager->Init();
196    connectionStateManager->RegisterObserver(observer);
197    connectionStateManager->UnregisterObserver(observer);
198    connectionStateManager->AddConnection(record);
199    connectionStateManager->RemoveConnection(record, boolParam);
200    connectionStateManager->AddDataAbilityConnection(dataCaller, dataAbility);
201    connectionStateManager->RemoveDataAbilityConnection(dataCaller, dataAbility);
202    connectionStateManager->CheckDataAbilityConnectionParams(dataCaller, dataAbility);
203    connectionStateManager->HandleDataAbilityDied(dataAbility);
204    connectionStateManager->HandleDataAbilityCallerDied(int32Param);
205#ifdef WITH_DLP
206    std::shared_ptr<AbilityRecord> dlpManger = GetFuzzAbilityRecord();
207    connectionStateManager->AddDlpManager(dlpManger);
208    connectionStateManager->RemoveDlpManager(dlpManger);
209    connectionStateManager->AddDlpAbility(dlpManger);
210    connectionStateManager->RemoveDlpAbility(dlpManger);
211#endif // WITH_DLP
212    connectionStateManager->HandleAppDied(int32Param);
213#ifdef WITH_DLP
214    std::vector<AbilityRuntime::DlpConnectionInfo> infos;
215    connectionStateManager->GetDlpConnectionInfos(infos);
216#endif // WITH_DLP
217    connectionStateManager->AddConnectionInner(connectionRecord, connectionData);
218    connectionStateManager->RemoveConnectionInner(connectionRecord, connectionData);
219    connectionStateManager->HandleCallerDied(int32Param);
220    connectionStateManager->RemoveDiedCaller(int32Param);
221    connectionStateManager->AddDataAbilityConnectionInner(dataCaller, dataAbility, connectionData);
222    connectionStateManager->RemoveDataAbilityConnectionInner(dataCaller, dataAbility, connectionData);
223    connectionStateManager->HandleDataAbilityDiedInner(token, datas);
224#ifdef WITH_DLP
225    AbilityRuntime::DlpStateData dlpData;
226    connectionStateManager->HandleDlpAbilityInner(dlpManger, boolParam, dlpData);
227#endif // WITH_DLP
228    connectionStateManager->InitAppStateObserver();
229    if (want) {
230        delete want;
231        want = nullptr;
232    }
233    return true;
234}
235}
236
237/* Fuzzer entry point */
238extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
239{
240    /* Run your code on data */
241    if (data == nullptr) {
242        return 0;
243    }
244
245    /* Validate the length of size */
246    if (size < OHOS::U32_AT_SIZE || size > OHOS::FOO_MAX_LEN) {
247        return 0;
248    }
249
250    char* ch = (char*)malloc(size + 1);
251    if (ch == nullptr) {
252        std::cout << "malloc failed." << std::endl;
253        return 0;
254    }
255
256    (void)memset_s(ch, size + 1, 0x00, size + 1);
257    if (memcpy_s(ch, size, data, size) != EOK) {
258        std::cout << "copy failed." << std::endl;
259        free(ch);
260        ch = nullptr;
261        return 0;
262    }
263
264    OHOS::DoSomethingInterestingWithMyAPI(ch, size);
265    free(ch);
266    ch = nullptr;
267    return 0;
268}
269
270