Added init_property_fuzzer
Test: ./init_property_fuzzer
Bug: 218631398
Change-Id: I1af733e7f82bef2979fc308b0109094b0ebe1e28
diff --git a/init/fuzzer/Android.bp b/init/fuzzer/Android.bp
index 28a65b2..b15b620 100644
--- a/init/fuzzer/Android.bp
+++ b/init/fuzzer/Android.bp
@@ -52,3 +52,11 @@
"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 902f30a..39cf6cf 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)
# <a name="InitParser"></a> Fuzzer for InitParser
@@ -24,3 +25,23 @@
$ 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
+```
diff --git a/init/fuzzer/init_property_fuzzer.cpp b/init/fuzzer/init_property_fuzzer.cpp
new file mode 100644
index 0000000..22df375
--- /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 <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;
+}