Merge changes I264d0891,I1af733e7,Iae344c1e
* changes: Added init_ueventHandler_fuzzer Added init_property_fuzzer Added init_parser_fuzzer
This commit is contained in:
commit
71d9f3607b
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
cc_defaults {
|
||||
name: "libinit_defaults",
|
||||
static_libs: [
|
||||
"libc++fs",
|
||||
"liblmkd_utils",
|
||||
"libmodprobe",
|
||||
"libprotobuf-cpp-lite",
|
||||
"libpropertyinfoparser",
|
||||
"libsnapshot_init",
|
||||
"libinit",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libfs_mgr",
|
||||
"libhidl-gen-utils",
|
||||
"libkeyutils",
|
||||
"liblog",
|
||||
"libprocessgroup",
|
||||
"libselinux",
|
||||
],
|
||||
header_libs: ["libinit_headers"],
|
||||
fuzz_config: {
|
||||
cc: [
|
||||
"android-media-fuzzing-reports@google.com",
|
||||
],
|
||||
componentid: 155276,
|
||||
},
|
||||
}
|
||||
|
||||
cc_fuzz {
|
||||
name: "init_parser_fuzzer",
|
||||
srcs: [
|
||||
"init_parser_fuzzer.cpp",
|
||||
],
|
||||
shared_libs: ["libhidlmetadata",],
|
||||
defaults: [
|
||||
"libinit_defaults",
|
||||
],
|
||||
}
|
||||
|
||||
cc_fuzz {
|
||||
name: "init_property_fuzzer",
|
||||
srcs: [
|
||||
"init_property_fuzzer.cpp",
|
||||
],
|
||||
defaults: ["libinit_defaults"],
|
||||
}
|
||||
|
||||
cc_fuzz {
|
||||
name: "init_ueventHandler_fuzzer",
|
||||
srcs: [
|
||||
"init_ueventHandler_fuzzer.cpp",
|
||||
],
|
||||
defaults: [
|
||||
"libinit_defaults",
|
||||
],
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
# Fuzzers for libinit
|
||||
|
||||
## Table of contents
|
||||
+ [init_parser_fuzzer](#InitParser)
|
||||
+ [init_property_fuzzer](#InitProperty)
|
||||
+ [init_ueventHandler_fuzzer](#InitUeventHandler)
|
||||
|
||||
# <a name="InitParser"></a> Fuzzer for InitParser
|
||||
|
||||
InitParser supports the following parameters:
|
||||
1. ValidPathNames (parameter name: "kValidPaths")
|
||||
2. ValidParseInputs (parameter name: "kValidInputs")
|
||||
|
||||
| Parameter| Valid Values| Configured Value|
|
||||
|------------- |-------------| ----- |
|
||||
|`kValidPaths`| 0.`/system/etc/init/hw/init.rc`,<br/> 1.`/system/etc/init` |Value obtained from FuzzedDataProvider|
|
||||
|`kValidInputs`| 0.`{"","cpu", "10", "10"}`,<br/> 1.`{"","RLIM_CPU", "10", "10"}`,<br/> 2.`{"","12", "unlimited", "10"}`,<br/> 3.`{"","13", "-1", "10"}`,<br/> 4.`{"","14", "10", "unlimited"}`,<br/> 5.`{"","15", "10", "-1"}` |Value obtained from FuzzedDataProvider|
|
||||
|
||||
#### Steps to run
|
||||
1. Build the fuzzer
|
||||
```
|
||||
$ mm -j$(nproc) init_parser_fuzzer
|
||||
```
|
||||
2. Run on device
|
||||
```
|
||||
$ adb sync data
|
||||
$ adb shell /data/fuzz/arm64/init_parser_fuzzer/init_parser_fuzzer
|
||||
```
|
||||
|
||||
# <a name="InitProperty"></a> Fuzzer for InitProperty
|
||||
|
||||
InitProperty supports the following parameters:
|
||||
PropertyType (parameter name: "PropertyType")
|
||||
|
||||
| Parameter| Valid Values |Configured Value|
|
||||
|-------------|----------|----- |
|
||||
|`PropertyType`| 0.`STRING`,<br/> 1.`BOOL`,<br/> 2.`INT`,<br/> 3.`UINT`,<br/> 4.`DOUBLE`,<br/> 5.`SIZE`,<br/>6.`ENUM`,<br/>7.`RANDOM`|Value obtained from FuzzedDataProvider|
|
||||
|
||||
#### Steps to run
|
||||
1. Build the fuzzer
|
||||
```
|
||||
$ mm -j$(nproc) init_property_fuzzer
|
||||
```
|
||||
2. Run on device
|
||||
```
|
||||
$ adb sync data
|
||||
$ adb shell /data/fuzz/arm64/init_property_fuzzer/init_property_fuzzer
|
||||
```
|
||||
|
||||
# <a name="InitUeventHandler"></a> Fuzzer for InitUeventHandler
|
||||
|
||||
##### Maximize code coverage
|
||||
The configuration parameters are not hardcoded, but instead selected based on
|
||||
incoming data. This ensures more code paths are reached by the fuzzer.
|
||||
|
||||
InitUeventHandler supports the following parameters:
|
||||
1. Major (parameter name: `major`)
|
||||
2. Minor (parameter name: `minor`)
|
||||
3. PartitionNum (parameter name: `partition_num`)
|
||||
4. Uid (parameter name: `uid`)
|
||||
5. Gid (parameter name: `gid`)
|
||||
6. Action (parameter name: `action`)
|
||||
7. Path (parameter name: `path`)
|
||||
8. Subsystem (parameter name: `subsystem`)
|
||||
9. PartitionName (parameter name: `partition_name`)
|
||||
10. DeviceName (parameter name: `device_name`)
|
||||
11. Modalias (parameter name: `modalias`)
|
||||
12. DevPath (parameter name: `devPath`)
|
||||
13. HandlerPath (parameter name: `handlerPath`)
|
||||
|
||||
| Parameter| Valid Values| Configured Value|
|
||||
|------------- |-------------| ----- |
|
||||
| `major` | `UINT32_MIN` to `UINT32_MAX` | Value obtained from FuzzedDataProvider|
|
||||
| `minor` | `UINT32_MIN` to `UINT32_MAX` | Value obtained from FuzzedDataProvider|
|
||||
| `partition_num ` | `UINT32_MIN` to `UINT32_MAX` | Value obtained from FuzzedDataProvider|
|
||||
| `uid` | `UINT32_MIN` to `UINT32_MAX` | Value obtained from FuzzedDataProvider|
|
||||
| `gid` | `UINT32_MIN` to `UINT32_MAX` | Value obtained from FuzzedDataProvider|
|
||||
| `action` | `String` | Value obtained from FuzzedDataProvider|
|
||||
| `path` | `String` | Value obtained from FuzzedDataProvider|
|
||||
| `subsystem` | `String` | Value obtained from FuzzedDataProvider|
|
||||
| `partition_name` | `String` | Value obtained from FuzzedDataProvider|
|
||||
| `device_name` | `String` | Value obtained from FuzzedDataProvider|
|
||||
| `modalias` | `String` | Value obtained from FuzzedDataProvider|
|
||||
| `devPath` | `String` | Value obtained from FuzzedDataProvider|
|
||||
| `handlerPath` | `String` | Value obtained from FuzzedDataProvider|
|
||||
|
||||
This also ensures that the plugin is always deterministic for any given input.
|
||||
|
||||
#### Steps to run
|
||||
1. Build the fuzzer
|
||||
```
|
||||
$ mm -j$(nproc) init_ueventHandler_fuzzer
|
||||
```
|
||||
2. Run on device
|
||||
```
|
||||
$ adb sync data
|
||||
$ adb shell /data/fuzz/arm64/init_ueventHandler_fuzzer/init_ueventHandler_fuzzer
|
||||
```
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* 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 <fuzzer/FuzzedDataProvider.h>
|
||||
#include <hidl/metadata.h>
|
||||
#include <import_parser.h>
|
||||
#include <interface_utils.h>
|
||||
#include <rlimit_parser.h>
|
||||
|
||||
using namespace android;
|
||||
using namespace android::init;
|
||||
|
||||
const std::vector<std::string> kValidInputs[] = {
|
||||
{"", "cpu", "10", "10"}, {"", "RLIM_CPU", "10", "10"}, {"", "12", "unlimited", "10"},
|
||||
{"", "13", "-1", "10"}, {"", "14", "10", "unlimited"}, {"", "15", "10", "-1"},
|
||||
};
|
||||
|
||||
const std::string kValidPaths[] = {
|
||||
"/system/etc/init/hw/init.rc",
|
||||
"/system/etc/init",
|
||||
};
|
||||
|
||||
const int32_t kMaxBytes = 256;
|
||||
const std::string kValidInterfaces = "android.frameworks.vr.composer@2.0::IVrComposerClient";
|
||||
|
||||
class InitParserFuzzer {
|
||||
public:
|
||||
InitParserFuzzer(const uint8_t* data, size_t size) : fdp_(data, size){};
|
||||
void Process();
|
||||
|
||||
private:
|
||||
void InvokeParser();
|
||||
void InvokeLimitParser();
|
||||
void InvokeInterfaceUtils();
|
||||
InterfaceInheritanceHierarchyMap GenerateHierarchyMap();
|
||||
std::vector<HidlInterfaceMetadata> GenerateInterfaceMetadata();
|
||||
|
||||
FuzzedDataProvider fdp_;
|
||||
};
|
||||
|
||||
void InitParserFuzzer::InvokeLimitParser() {
|
||||
if (fdp_.ConsumeBool()) {
|
||||
std::vector<std::string> input;
|
||||
input.push_back("");
|
||||
input.push_back(fdp_.ConsumeRandomLengthString(kMaxBytes));
|
||||
input.push_back(fdp_.ConsumeRandomLengthString(kMaxBytes));
|
||||
input.push_back(fdp_.ConsumeRandomLengthString(kMaxBytes));
|
||||
ParseRlimit(input);
|
||||
} else {
|
||||
ParseRlimit(fdp_.PickValueInArray(kValidInputs));
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<HidlInterfaceMetadata> InitParserFuzzer::GenerateInterfaceMetadata() {
|
||||
std::vector<HidlInterfaceMetadata> random_interface;
|
||||
for (size_t idx = 0; idx < fdp_.ConsumeIntegral<size_t>(); ++idx) {
|
||||
HidlInterfaceMetadata metadata;
|
||||
metadata.name = fdp_.ConsumeRandomLengthString(kMaxBytes);
|
||||
for (size_t idx1 = 0; idx1 < fdp_.ConsumeIntegral<size_t>(); ++idx1) {
|
||||
metadata.inherited.push_back(fdp_.ConsumeRandomLengthString(kMaxBytes));
|
||||
}
|
||||
random_interface.push_back(metadata);
|
||||
}
|
||||
return random_interface;
|
||||
}
|
||||
|
||||
InterfaceInheritanceHierarchyMap InitParserFuzzer::GenerateHierarchyMap() {
|
||||
InterfaceInheritanceHierarchyMap result;
|
||||
std::vector<HidlInterfaceMetadata> random_interface;
|
||||
if (fdp_.ConsumeBool()) {
|
||||
random_interface = GenerateInterfaceMetadata();
|
||||
} else {
|
||||
random_interface = HidlInterfaceMetadata::all();
|
||||
}
|
||||
|
||||
for (const HidlInterfaceMetadata& iface : random_interface) {
|
||||
std::set<FQName> inherited_interfaces;
|
||||
for (const std::string& intf : iface.inherited) {
|
||||
FQName fqname;
|
||||
(void)fqname.setTo(intf);
|
||||
inherited_interfaces.insert(fqname);
|
||||
}
|
||||
FQName fqname;
|
||||
(void)fqname.setTo(iface.name);
|
||||
result[fqname] = inherited_interfaces;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void InitParserFuzzer::InvokeInterfaceUtils() {
|
||||
InterfaceInheritanceHierarchyMap hierarchy_map = GenerateHierarchyMap();
|
||||
SetKnownInterfaces(hierarchy_map);
|
||||
IsKnownInterface(fdp_.ConsumeRandomLengthString(kMaxBytes));
|
||||
std::set<std::string> interface_set;
|
||||
for (size_t idx = 0; idx < fdp_.ConsumeIntegral<size_t>(); ++idx) {
|
||||
auto set_interface_values = fdp_.PickValueInArray<const std::function<void()>>({
|
||||
[&]() {
|
||||
interface_set.insert(("aidl/" + fdp_.ConsumeRandomLengthString(kMaxBytes)));
|
||||
},
|
||||
[&]() { interface_set.insert(fdp_.ConsumeRandomLengthString(kMaxBytes)); },
|
||||
[&]() { interface_set.insert(kValidInterfaces); },
|
||||
});
|
||||
set_interface_values();
|
||||
}
|
||||
CheckInterfaceInheritanceHierarchy(interface_set, hierarchy_map);
|
||||
}
|
||||
|
||||
void InitParserFuzzer::InvokeParser() {
|
||||
Parser parser;
|
||||
std::string name = fdp_.ConsumeBool() ? fdp_.ConsumeRandomLengthString(kMaxBytes) : "import";
|
||||
parser.AddSectionParser(name, std::make_unique<ImportParser>(&parser));
|
||||
std::string path = fdp_.ConsumeBool() ? fdp_.PickValueInArray(kValidPaths)
|
||||
: fdp_.ConsumeRandomLengthString(kMaxBytes);
|
||||
parser.ParseConfig(path);
|
||||
parser.ParseConfigFileInsecure(path);
|
||||
}
|
||||
|
||||
void InitParserFuzzer::Process() {
|
||||
while (fdp_.remaining_bytes()) {
|
||||
auto invoke_parser_fuzzer = fdp_.PickValueInArray<const std::function<void()>>({
|
||||
[&]() { InvokeParser(); },
|
||||
[&]() { InvokeInterfaceUtils(); },
|
||||
[&]() { InvokeLimitParser(); },
|
||||
});
|
||||
invoke_parser_fuzzer();
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
InitParserFuzzer init_parser_fuzzer(data, size);
|
||||
init_parser_fuzzer.Process();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* 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 <persistent_properties.h>
|
||||
#include <property_type.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fstream>
|
||||
#include "fuzzer/FuzzedDataProvider.h"
|
||||
|
||||
using namespace android;
|
||||
using namespace android::init;
|
||||
using android::init::persistent_property_filename;
|
||||
|
||||
const std::string kTempDir = "/data/local/tmp/";
|
||||
const std::string kFuzzerPropertyFile = kTempDir + "persistent_properties";
|
||||
constexpr int32_t kMaxPropertyLength = 10;
|
||||
const std::string kPrefix = "persist.";
|
||||
const std::string kPropertyName = kPrefix + "sys.timezone";
|
||||
const std::string kPropertyValue = "America/Los_Angeles";
|
||||
const std::string kLegacyPropertyFile = "/data/property/persist.properties";
|
||||
const std::string kSizeSuffix[3] = {"g", "k", "m"};
|
||||
constexpr int32_t kMinNumStrings = 1;
|
||||
constexpr int32_t kMaxNumStrings = 10;
|
||||
|
||||
enum PropertyType { STRING, BOOL, INT, UINT, DOUBLE, SIZE, ENUM, RANDOM, kMaxValue = RANDOM };
|
||||
|
||||
class InitPropertyFuzzer {
|
||||
public:
|
||||
InitPropertyFuzzer(const uint8_t* data, size_t size) : fdp_(data, size){};
|
||||
void process();
|
||||
|
||||
private:
|
||||
void InvokeCheckType();
|
||||
void InvokeWritePersistentProperty();
|
||||
void RemoveFiles();
|
||||
void CreateFuzzerPropertyFile(const std::string property_file);
|
||||
FuzzedDataProvider fdp_;
|
||||
};
|
||||
|
||||
void InitPropertyFuzzer::InvokeCheckType() {
|
||||
std::string property_type;
|
||||
std::string value;
|
||||
int type = fdp_.ConsumeEnum<PropertyType>();
|
||||
switch (type) {
|
||||
case STRING:
|
||||
value = fdp_.ConsumeRandomLengthString(kMaxPropertyLength);
|
||||
property_type = "string";
|
||||
break;
|
||||
case BOOL:
|
||||
value = fdp_.ConsumeBool();
|
||||
property_type = "bool";
|
||||
break;
|
||||
case INT:
|
||||
value = fdp_.ConsumeIntegral<int>();
|
||||
property_type = "int";
|
||||
break;
|
||||
case UINT:
|
||||
value = fdp_.ConsumeIntegral<uint_t>();
|
||||
property_type = "uint";
|
||||
break;
|
||||
case DOUBLE:
|
||||
value = fdp_.ConsumeFloatingPoint<double>();
|
||||
property_type = "double";
|
||||
break;
|
||||
case SIZE:
|
||||
value = fdp_.ConsumeIntegral<uint_t>();
|
||||
value = value.append(fdp_.PickValueInArray(kSizeSuffix));
|
||||
property_type = "size";
|
||||
break;
|
||||
case ENUM:
|
||||
value = fdp_.ConsumeIntegral<uint_t>();
|
||||
property_type = "enum";
|
||||
break;
|
||||
case RANDOM:
|
||||
value = fdp_.ConsumeRandomLengthString(kMaxPropertyLength);
|
||||
property_type = fdp_.ConsumeRandomLengthString(kMaxPropertyLength);
|
||||
break;
|
||||
}
|
||||
|
||||
CheckType(property_type, value);
|
||||
}
|
||||
|
||||
void InitPropertyFuzzer::InvokeWritePersistentProperty() {
|
||||
if (fdp_.ConsumeBool()) {
|
||||
WritePersistentProperty(kPropertyName, kPropertyValue);
|
||||
} else {
|
||||
WritePersistentProperty((kPrefix + fdp_.ConsumeRandomLengthString(kMaxPropertyLength)),
|
||||
fdp_.ConsumeRandomLengthString(kMaxPropertyLength));
|
||||
}
|
||||
}
|
||||
|
||||
void InitPropertyFuzzer::RemoveFiles() {
|
||||
remove(kFuzzerPropertyFile.c_str());
|
||||
remove(kLegacyPropertyFile.c_str());
|
||||
}
|
||||
|
||||
void InitPropertyFuzzer::CreateFuzzerPropertyFile(const std::string property_file) {
|
||||
std::ofstream out;
|
||||
out.open(property_file, std::ios::binary | std::ofstream::trunc);
|
||||
chmod(property_file.c_str(), S_IRWXU);
|
||||
const int32_t numStrings = fdp_.ConsumeIntegralInRange(kMinNumStrings, kMaxNumStrings);
|
||||
for (int32_t i = 0; i < numStrings; ++i) {
|
||||
out << fdp_.ConsumeRandomLengthString(kMaxPropertyLength) << "\n";
|
||||
}
|
||||
out.close();
|
||||
}
|
||||
|
||||
void InitPropertyFuzzer::process() {
|
||||
persistent_property_filename = kFuzzerPropertyFile;
|
||||
/* Property and legacy files are created using createFuzzerPropertyFile() and */
|
||||
/* are used in the below APIs. Hence createFuzzerPropertyFile() is not a part */
|
||||
/* of the lambda construct. */
|
||||
CreateFuzzerPropertyFile(kFuzzerPropertyFile);
|
||||
CreateFuzzerPropertyFile(kLegacyPropertyFile);
|
||||
auto property_type = fdp_.PickValueInArray<const std::function<void()>>({
|
||||
[&]() { InvokeCheckType(); },
|
||||
[&]() { InvokeWritePersistentProperty(); },
|
||||
[&]() { LoadPersistentProperties(); },
|
||||
});
|
||||
property_type();
|
||||
RemoveFiles();
|
||||
}
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
InitPropertyFuzzer initPropertyFuzzer(data, size);
|
||||
initPropertyFuzzer.process();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* 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 <devices.h>
|
||||
#include <firmware_handler.h>
|
||||
#include <fuzzer/FuzzedDataProvider.h>
|
||||
#include <modalias_handler.h>
|
||||
#include <sys/stat.h>
|
||||
#include <util.h>
|
||||
#include <fstream>
|
||||
|
||||
using namespace android;
|
||||
using namespace android::init;
|
||||
constexpr int32_t kMaxBytes = 100;
|
||||
constexpr int32_t kMaxSize = 1000;
|
||||
constexpr int32_t kMinSize = 1;
|
||||
|
||||
/*'HandleUevent' prefixes the path with '/sys' and hence this is required to point
|
||||
* to'/data/local/tmp' dir.*/
|
||||
const std::string kPath = "/../data/local/tmp/";
|
||||
const std::string kPathPrefix = "/..";
|
||||
|
||||
void MakeFile(FuzzedDataProvider* fdp, std::string s) {
|
||||
std::ofstream out;
|
||||
out.open(s, std::ios::binary | std::ofstream::trunc);
|
||||
for (int32_t idx = 0; idx < fdp->ConsumeIntegralInRange(kMinSize, kMaxSize); ++idx) {
|
||||
out << fdp->ConsumeRandomLengthString(kMaxBytes) << "\n";
|
||||
}
|
||||
out.close();
|
||||
}
|
||||
|
||||
void CreateDir(std::string Directory, FuzzedDataProvider* fdp) {
|
||||
std::string tmp = Directory.substr(kPathPrefix.length());
|
||||
mkdir_recursive(android::base::Dirname(tmp.c_str()),
|
||||
S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||
MakeFile(fdp, tmp + "/data");
|
||||
MakeFile(fdp, tmp + "/loading");
|
||||
}
|
||||
|
||||
std::string SelectRandomString(FuzzedDataProvider* fdp, std::string s) {
|
||||
if (fdp->ConsumeBool()) {
|
||||
if (fdp->ConsumeBool()) {
|
||||
return fdp->ConsumeRandomLengthString(kMaxBytes);
|
||||
} else {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
Uevent CreateUevent(FuzzedDataProvider* fdp) {
|
||||
Uevent uevent;
|
||||
uevent.action = SelectRandomString(fdp, "add");
|
||||
uevent.subsystem = SelectRandomString(fdp, "firmware");
|
||||
uevent.path = SelectRandomString(fdp, kPath + fdp->ConsumeRandomLengthString(kMaxBytes));
|
||||
uevent.firmware = fdp->ConsumeBool() ? fdp->ConsumeRandomLengthString(kMaxBytes) : "";
|
||||
uevent.partition_name = fdp->ConsumeBool() ? fdp->ConsumeRandomLengthString(kMaxBytes) : "";
|
||||
uevent.device_name = fdp->ConsumeBool() ? fdp->ConsumeRandomLengthString(kMaxBytes) : "";
|
||||
uevent.modalias = fdp->ConsumeBool() ? fdp->ConsumeRandomLengthString(kMaxBytes) : "";
|
||||
uevent.partition_num = fdp->ConsumeIntegral<int32_t>();
|
||||
uevent.major = fdp->ConsumeIntegral<int32_t>();
|
||||
uevent.minor = fdp->ConsumeIntegral<int32_t>();
|
||||
return uevent;
|
||||
}
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
FuzzedDataProvider fdp(data, size);
|
||||
while (fdp.remaining_bytes()) {
|
||||
auto invoke_uevent_handler_fuzzer = fdp.PickValueInArray<const std::function<void()>>({
|
||||
[&]() {
|
||||
std::vector<std::string> modalias_vector;
|
||||
for (size_t idx = 0;
|
||||
idx < fdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize); ++idx) {
|
||||
modalias_vector.push_back(fdp.ConsumeRandomLengthString(kMaxBytes));
|
||||
}
|
||||
ModaliasHandler modalias_handler = ModaliasHandler(modalias_vector);
|
||||
modalias_handler.HandleUevent(CreateUevent(&fdp));
|
||||
},
|
||||
[&]() {
|
||||
std::vector<ExternalFirmwareHandler> external_handlers;
|
||||
std::vector<std::string> firmware_directories;
|
||||
for (size_t idx = 0;
|
||||
idx < fdp.ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize); ++idx) {
|
||||
std::string devPath = fdp.ConsumeRandomLengthString(kMaxBytes);
|
||||
uid_t uid = fdp.ConsumeIntegral<uid_t>();
|
||||
gid_t gid = fdp.ConsumeIntegral<gid_t>();
|
||||
std::string handlerPath = fdp.ConsumeRandomLengthString(kMaxBytes);
|
||||
ExternalFirmwareHandler externalFirmwareHandler =
|
||||
ExternalFirmwareHandler(devPath, uid, gid, handlerPath);
|
||||
external_handlers.push_back(externalFirmwareHandler);
|
||||
firmware_directories.push_back(fdp.ConsumeRandomLengthString(kMaxBytes));
|
||||
}
|
||||
FirmwareHandler firmware_handler =
|
||||
FirmwareHandler(firmware_directories, external_handlers);
|
||||
Uevent uevent = CreateUevent(&fdp);
|
||||
if (fdp.ConsumeBool() && uevent.path.size() != 0 &&
|
||||
uevent.path.find(kPath) == 0) {
|
||||
CreateDir(uevent.path, &fdp);
|
||||
firmware_handler.HandleUevent(uevent);
|
||||
std::string s = uevent.path.substr(kPathPrefix.length());
|
||||
remove(s.c_str());
|
||||
} else {
|
||||
firmware_handler.HandleUevent(uevent);
|
||||
}
|
||||
},
|
||||
});
|
||||
invoke_uevent_handler_fuzzer();
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue