* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "sta_fuzzer.h"
#include "wlan_common_fuzzer.h"
namespace OHOS {
namespace WIFI {
constexpr size_t THRESHOLD = 10;
const char *g_wlanServiceName = "wlan_interface_service";
const int32_t wlanType = PROTOCOL_80211_IFTYPE_STATION;
struct IWlanInterface *g_wlanObj = nullptr;
static void FuzzStartScan(struct IWlanInterface *interface, const uint8_t *rawData)
{
struct HdfWifiScan scan = {0};
struct HdfFeatureInfo feature;
feature.ifName = const_cast<char *>(reinterpret_cast<const char *>(rawData));
feature.type = *const_cast<int32_t *>(reinterpret_cast<const int32_t *>(rawData));
interface->StartScan(interface, &feature, &scan);
HDF_LOGI("%{public}s: success", __FUNCTION__);
}
static void FuzzSetScanningMacAddress(struct IWlanInterface *interface, const uint8_t *rawData)
{
struct HdfFeatureInfo feature;
feature.ifName = const_cast<char *>(reinterpret_cast<const char *>(rawData));
feature.type = *const_cast<int32_t *>(reinterpret_cast<const int32_t *>(rawData));
const uint8_t *scanMac = rawData;
uint32_t macLen = 0;
if (GetWlanDataSize(&macLen) != HDF_SUCCESS) {
HDF_LOGE("%{public}s: get data size failed!", __FUNCTION__);
}
interface->SetScanningMacAddress(interface, &feature, scanMac, macLen);
HDF_LOGI("%{public}s: success", __FUNCTION__);
}
static FuzzWlanFuncs g_fuzzWlanFuncs[] = {
FuzzStartScan,
FuzzGetChipId,
FuzzGetDeviceMacAddress,
FuzzGetFeatureType,
FuzzGetFreqsWithBand,
FuzzGetNetworkIfaceName,
FuzzSetMacAddress,
FuzzSetTxPower,
FuzzGetPowerMode,
FuzzSetPowerMode,
FuzzGetIfNamesByChipId,
FuzzResetDriver,
FuzzStartChannelMeas,
FuzzSetProjectionScreenParam,
FuzzWifiSendCmdIoctl,
FuzzGetFeatureByIfName,
FuzzGetStaInfo,
FuzzGetChannelMeasResult,
FuzzSetScanningMacAddress,
FuzzResetToFactoryMacAddress,
};
static void FuncToOptimal(struct IWlanInterface *interface, uint32_t cmdId, const uint8_t *data)
{
FuzzWlanFuncs fuzzWlanFunc = g_fuzzWlanFuncs[cmdId];
if (fuzzWlanFunc != nullptr) {
fuzzWlanFunc(interface, data);
}
return;
}
bool DoSomethingInterestingWithMyAPI(const uint8_t *rawData, size_t size)
{
struct HdfFeatureInfo ifeature;
bool result = false;
if (rawData == nullptr || size == 0) {
return false;
}
uint32_t cmdId = Convert2Uint32(rawData) % ((sizeof(g_fuzzWlanFuncs) / sizeof(g_fuzzWlanFuncs[0])));
g_wlanObj = IWlanInterfaceGetInstance(g_wlanServiceName, false);
if (g_wlanObj == nullptr) {
HDF_LOGE("%{public}s: g_wlanObj is null", __FUNCTION__);
return result;
}
uint32_t dataSize = size - OFFSET;
uint8_t *tmpRawData = reinterpret_cast<uint8_t *>(OsalMemCalloc(dataSize + 1));
if (tmpRawData == nullptr) {
HDF_LOGE("%{public}s: OsalMemCalloc failed!", __FUNCTION__);
return result;
}
int32_t ret = g_wlanObj->Start(g_wlanObj);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%{public}s: Start failed! ret=%{public}d", __FUNCTION__, ret);
OsalMemFree(tmpRawData);
return result;
}
do {
if (PreProcessRawData(rawData, size, tmpRawData, dataSize + 1) != true) {
break;
}
ret = g_wlanObj->CreateFeature(g_wlanObj, wlanType, &ifeature);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%{public}s: CreateFeature failed! ret=%{public}d", __FUNCTION__, ret);
break;
}
FuncToOptimal(g_wlanObj, cmdId, tmpRawData);
ret = g_wlanObj->DestroyFeature(g_wlanObj, &ifeature);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%{public}s: DestroyFeature failed! ret=%{public}d", __FUNCTION__, ret);
break;
}
result = true;
} while (false);
ret = g_wlanObj->Stop(g_wlanObj);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%{public}s: Stop failed! ret=%{public}d", __FUNCTION__, ret);
result = false;
}
IWlanInterfaceReleaseInstance(g_wlanServiceName, g_wlanObj, false);
OsalMemFree(tmpRawData);
return result;
}
}
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
if (size < OHOS::WIFI::THRESHOLD) {
return 0;
}
OHOS::WIFI::DoSomethingInterestingWithMyAPI(data, size);
return 0;
}