From 2ae767105d137a051c30336a61d6d15899a6f370 Mon Sep 17 00:00:00 2001 From: Akshata Kadam Date: Tue, 26 Apr 2022 09:52:28 +0530 Subject: [PATCH] Added init_property_fuzzer Test: ./init_property_fuzzer Bug: 218631398 Change-Id: I1af733e7f82bef2979fc308b0109094b0ebe1e28 --- init/fuzzer/Android.bp | 8 ++ init/fuzzer/README.md | 21 ++++ init/fuzzer/init_property_fuzzer.cpp | 140 +++++++++++++++++++++++++++ 3 files changed, 169 insertions(+) create mode 100644 init/fuzzer/init_property_fuzzer.cpp diff --git a/init/fuzzer/Android.bp b/init/fuzzer/Android.bp index 28a65b20e..b15b620df 100644 --- a/init/fuzzer/Android.bp +++ b/init/fuzzer/Android.bp @@ -52,3 +52,11 @@ cc_fuzz { "libinit_defaults", ], } + +cc_fuzz { + name: "init_property_fuzzer", + srcs: [ + "init_property_fuzzer.cpp", + ], + defaults: ["libinit_defaults"], +} diff --git a/init/fuzzer/README.md b/init/fuzzer/README.md index 902f30a89..39cf6cfae 100644 --- a/init/fuzzer/README.md +++ b/init/fuzzer/README.md @@ -2,6 +2,7 @@ ## Table of contents + [init_parser_fuzzer](#InitParser) ++ [init_property_fuzzer](#InitProperty) # 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 ``` + +# Fuzzer for InitProperty + +InitProperty supports the following parameters: + PropertyType (parameter name: "PropertyType") + +| Parameter| Valid Values |Configured Value| +|-------------|----------|----- | +|`PropertyType`| 0.`STRING`,
1.`BOOL`,
2.`INT`,
3.`UINT`,
4.`DOUBLE`,
5.`SIZE`,
6.`ENUM`,
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 +``` diff --git a/init/fuzzer/init_property_fuzzer.cpp b/init/fuzzer/init_property_fuzzer.cpp new file mode 100644 index 000000000..22df37559 --- /dev/null +++ b/init/fuzzer/init_property_fuzzer.cpp @@ -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 +#include +#include +#include +#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(); + 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(); + property_type = "int"; + break; + case UINT: + value = fdp_.ConsumeIntegral(); + property_type = "uint"; + break; + case DOUBLE: + value = fdp_.ConsumeFloatingPoint(); + property_type = "double"; + break; + case SIZE: + value = fdp_.ConsumeIntegral(); + value = value.append(fdp_.PickValueInArray(kSizeSuffix)); + property_type = "size"; + break; + case ENUM: + value = fdp_.ConsumeIntegral(); + 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>({ + [&]() { 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; +}