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#include "sta_fuzzer.h"
16#include "wlan_common_fuzzer.h"
17
18namespace OHOS {
19namespace WIFI {
20constexpr size_t THRESHOLD = 10;
21const char *g_wlanServiceName = "wlan_interface_service";
22const int32_t wlanType = PROTOCOL_80211_IFTYPE_STATION;
23struct IWlanInterface *g_wlanObj = nullptr;
24
25static void FuzzStartScan(struct IWlanInterface *interface, const uint8_t *rawData)
26{
27    struct HdfWifiScan scan = {0};
28    struct HdfFeatureInfo feature;
29    feature.ifName = const_cast<char *>(reinterpret_cast<const char *>(rawData));
30    feature.type = *const_cast<int32_t *>(reinterpret_cast<const int32_t *>(rawData));
31
32    interface->StartScan(interface, &feature, &scan);
33    HDF_LOGI("%{public}s: success", __FUNCTION__);
34}
35
36static void FuzzSetScanningMacAddress(struct IWlanInterface *interface, const uint8_t *rawData)
37{
38    struct HdfFeatureInfo feature;
39    feature.ifName = const_cast<char *>(reinterpret_cast<const char *>(rawData));
40    feature.type = *const_cast<int32_t *>(reinterpret_cast<const int32_t *>(rawData));
41    const uint8_t *scanMac = rawData;
42    uint32_t macLen = 0;
43
44    if (GetWlanDataSize(&macLen) != HDF_SUCCESS) {
45        HDF_LOGE("%{public}s: get data size failed!", __FUNCTION__);
46    }
47
48    interface->SetScanningMacAddress(interface, &feature, scanMac, macLen);
49    HDF_LOGI("%{public}s: success", __FUNCTION__);
50}
51
52static FuzzWlanFuncs g_fuzzWlanFuncs[] = {
53    FuzzStartScan,
54    FuzzGetChipId,
55    FuzzGetDeviceMacAddress,
56    FuzzGetFeatureType,
57    FuzzGetFreqsWithBand,
58    FuzzGetNetworkIfaceName,
59    FuzzSetMacAddress,
60    FuzzSetTxPower,
61    FuzzGetPowerMode,
62    FuzzSetPowerMode,
63    FuzzGetIfNamesByChipId,
64    FuzzResetDriver,
65    FuzzStartChannelMeas,
66    FuzzSetProjectionScreenParam,
67    FuzzWifiSendCmdIoctl,
68    FuzzGetFeatureByIfName,
69    FuzzGetStaInfo,
70    FuzzGetChannelMeasResult,
71    FuzzSetScanningMacAddress,
72    FuzzResetToFactoryMacAddress,
73};
74
75static void FuncToOptimal(struct IWlanInterface *interface, uint32_t cmdId, const uint8_t *data)
76{
77    FuzzWlanFuncs fuzzWlanFunc = g_fuzzWlanFuncs[cmdId];
78    if (fuzzWlanFunc != nullptr) {
79        fuzzWlanFunc(interface, data);
80    }
81    return;
82}
83
84bool DoSomethingInterestingWithMyAPI(const uint8_t *rawData, size_t size)
85{
86    struct HdfFeatureInfo ifeature;
87    bool result = false;
88
89    if (rawData == nullptr || size == 0) {
90        return false;
91    }
92
93    uint32_t cmdId = Convert2Uint32(rawData) % ((sizeof(g_fuzzWlanFuncs) / sizeof(g_fuzzWlanFuncs[0])));
94    g_wlanObj = IWlanInterfaceGetInstance(g_wlanServiceName, false);
95    if (g_wlanObj == nullptr) {
96        HDF_LOGE("%{public}s: g_wlanObj is null", __FUNCTION__);
97        return result;
98    }
99    uint32_t dataSize = size - OFFSET;
100    uint8_t *tmpRawData = reinterpret_cast<uint8_t *>(OsalMemCalloc(dataSize + 1));
101    if (tmpRawData == nullptr) {
102        HDF_LOGE("%{public}s: OsalMemCalloc failed!", __FUNCTION__);
103        return result;
104    }
105    int32_t ret = g_wlanObj->Start(g_wlanObj);
106    if (ret != HDF_SUCCESS) {
107        HDF_LOGE("%{public}s: Start failed! ret=%{public}d", __FUNCTION__, ret);
108        OsalMemFree(tmpRawData);
109        return result;
110    }
111    do {
112        if (PreProcessRawData(rawData, size, tmpRawData, dataSize + 1) != true) {
113            break;
114        }
115        ret = g_wlanObj->CreateFeature(g_wlanObj, wlanType, &ifeature);
116        if (ret != HDF_SUCCESS) {
117            HDF_LOGE("%{public}s: CreateFeature failed! ret=%{public}d", __FUNCTION__, ret);
118            break;
119        }
120        FuncToOptimal(g_wlanObj, cmdId, tmpRawData);
121        ret = g_wlanObj->DestroyFeature(g_wlanObj, &ifeature);
122        if (ret != HDF_SUCCESS) {
123            HDF_LOGE("%{public}s: DestroyFeature failed! ret=%{public}d", __FUNCTION__, ret);
124            break;
125        }
126        result = true;
127    } while (false);
128    ret = g_wlanObj->Stop(g_wlanObj);
129    if (ret != HDF_SUCCESS) {
130        HDF_LOGE("%{public}s: Stop failed! ret=%{public}d", __FUNCTION__, ret);
131        result = false;
132    }
133    IWlanInterfaceReleaseInstance(g_wlanServiceName, g_wlanObj, false);
134    OsalMemFree(tmpRawData);
135    return result;
136}
137} // namespace WIFI
138} // namespace OHOS
139
140/* Fuzzer entry point */
141extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
142{
143    if (size < OHOS::WIFI::THRESHOLD) {
144        return 0;
145    }
146
147    /* Run your code on data */
148    OHOS::WIFI::DoSomethingInterestingWithMyAPI(data, size);
149    return 0;
150}
151