Added init_property_fuzzer

Test: ./init_property_fuzzer
Bug: 218631398

Change-Id: I1af733e7f82bef2979fc308b0109094b0ebe1e28
This commit is contained in:
Akshata Kadam 2022-04-26 09:52:28 +05:30 committed by Devendra Singhi
parent d29be4aaa0
commit 2ae767105d
3 changed files with 169 additions and 0 deletions

View file

@ -52,3 +52,11 @@ cc_fuzz {
"libinit_defaults",
],
}
cc_fuzz {
name: "init_property_fuzzer",
srcs: [
"init_property_fuzzer.cpp",
],
defaults: ["libinit_defaults"],
}

View file

@ -2,6 +2,7 @@
## Table of contents
+ [init_parser_fuzzer](#InitParser)
+ [init_property_fuzzer](#InitProperty)
# <a name="InitParser"></a> Fuzzer for InitParser
@ -24,3 +25,23 @@ InitParser supports the following parameters:
$ 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
```

View file

@ -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;
}