Add second batch of fuzzers for libutils

This adds fuzzers for:
- CallStack
- Looper
- LruCache
- Printer
- ProcessCallStack
- PropertyMap
- RWLock
- RefBase
- StopWatch.
Test: Ran each fuzzer for 10 minutes. Rough coverage est. (likely far below actual value): 10.97%

Signed-off-by: Dylan Katz <dylan.katz@leviathansecurity.com>
Change-Id: I2f9f35c18b13338c282fb7f9c3ea4099ecb2c56f
diff --git a/libutils/Android.bp b/libutils/Android.bp
index 9bd15c6..05be220 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -205,6 +205,7 @@
     shared_libs: [
         "libutils",
         "libbase",
+        "liblog",
     ],
 }
 
@@ -238,6 +239,66 @@
     srcs: ["Vector_fuzz.cpp"],
 }
 
+cc_fuzz {
+    name: "libutils_fuzz_printer",
+    defaults: ["libutils_fuzz_defaults"],
+    srcs: ["Printer_fuzz.cpp"],
+}
+
+cc_fuzz {
+    name: "libutils_fuzz_callstack",
+    defaults: ["libutils_fuzz_defaults"],
+    srcs: ["CallStack_fuzz.cpp"],
+    shared_libs: [
+        "libutilscallstack",
+    ],
+}
+
+cc_fuzz {
+    name: "libutils_fuzz_process_callstack",
+    defaults: ["libutils_fuzz_defaults"],
+    srcs: ["ProcessCallStack_fuzz.cpp"],
+    shared_libs: [
+        "libutilscallstack",
+    ],
+}
+
+cc_fuzz {
+    name: "libutils_fuzz_stopwatch",
+    defaults: ["libutils_fuzz_defaults"],
+    srcs: ["StopWatch_fuzz.cpp"],
+}
+
+cc_fuzz {
+    name: "libutils_fuzz_propertymap",
+    defaults: ["libutils_fuzz_defaults"],
+    srcs: ["PropertyMap_fuzz.cpp"],
+}
+
+cc_fuzz {
+    name: "libutils_fuzz_rwlock",
+    defaults: ["libutils_fuzz_defaults"],
+    srcs: ["RWLock_fuzz.cpp"],
+}
+
+cc_fuzz {
+    name: "libutils_fuzz_refbase",
+    defaults: ["libutils_fuzz_defaults"],
+    srcs: ["RefBase_fuzz.cpp"],
+}
+
+cc_fuzz {
+    name: "libutils_fuzz_lrucache",
+    defaults: ["libutils_fuzz_defaults"],
+    srcs: ["LruCache_fuzz.cpp"],
+}
+
+cc_fuzz {
+    name: "libutils_fuzz_looper",
+    defaults: ["libutils_fuzz_defaults"],
+    srcs: ["Looper_fuzz.cpp"],
+}
+
 cc_test {
     name: "libutils_test",
     host_supported: true,
diff --git a/libutils/CallStack_fuzz.cpp b/libutils/CallStack_fuzz.cpp
new file mode 100644
index 0000000..e89b5b7
--- /dev/null
+++ b/libutils/CallStack_fuzz.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2020 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 <memory.h>
+
+#include "fuzzer/FuzzedDataProvider.h"
+#include "utils/CallStack.h"
+
+static constexpr int MAX_STRING_SIZE = 500;
+static constexpr int MAX_IGNORE_DEPTH = 200;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    FuzzedDataProvider dataProvider(data, size);
+    size_t ignoreDepth = dataProvider.ConsumeIntegralInRange<size_t>(0, MAX_IGNORE_DEPTH);
+    int logPriority = dataProvider.ConsumeIntegral<int>();
+    pid_t tid = dataProvider.ConsumeIntegral<pid_t>();
+    std::string logTag = dataProvider.ConsumeRandomLengthString(MAX_STRING_SIZE);
+    std::string prefix = dataProvider.ConsumeRandomLengthString(MAX_STRING_SIZE);
+
+    const char* logTagChars = logTag.c_str();
+    const char* prefixChars = prefix.c_str();
+
+    android::CallStack::CallStackUPtr callStack = android::CallStack::getCurrent(ignoreDepth);
+    android::CallStack* callstackPtr = callStack.get();
+    android::CallStack::logStack(logTagChars, callstackPtr,
+                                 static_cast<android_LogPriority>(logPriority));
+    android::CallStack::stackToString(prefixChars);
+
+    callstackPtr->log(logTagChars, static_cast<android_LogPriority>(logPriority), prefixChars);
+    callstackPtr->clear();
+    callstackPtr->getCurrent(ignoreDepth);
+    callstackPtr->log(logTagChars, static_cast<android_LogPriority>(logPriority), prefixChars);
+    callstackPtr->update(ignoreDepth, tid);
+    callstackPtr->log(logTagChars, static_cast<android_LogPriority>(logPriority), prefixChars);
+
+    return 0;
+}
diff --git a/libutils/Looper_fuzz.cpp b/libutils/Looper_fuzz.cpp
new file mode 100644
index 0000000..c3ae54e
--- /dev/null
+++ b/libutils/Looper_fuzz.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2020 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 <sys/select.h>
+
+#include <iostream>
+
+#include <utils/Looper.h>
+
+#include "Looper_test_pipe.h"
+#include "fuzzer/FuzzedDataProvider.h"
+
+using android::Looper;
+using android::sp;
+
+// We don't want this to bog down fuzzing
+static constexpr int MAX_POLL_DELAY = 50;
+static constexpr int MAX_OPERATIONS = 500;
+
+void doNothing() {}
+void* doNothingPointer = reinterpret_cast<void*>(doNothing);
+
+static int noopCallback(int, int, void*) {
+    return 0;
+}
+
+std::vector<std::function<void(FuzzedDataProvider*, sp<Looper>, Pipe)>> operations = {
+        [](FuzzedDataProvider* dataProvider, sp<Looper> looper, Pipe) -> void {
+            looper->pollOnce(dataProvider->ConsumeIntegralInRange<int>(0, MAX_POLL_DELAY));
+        },
+        [](FuzzedDataProvider* dataProvider, sp<Looper> looper, Pipe) -> void {
+            looper->pollAll(dataProvider->ConsumeIntegralInRange<int>(0, MAX_POLL_DELAY));
+        },
+        // events and callback are nullptr
+        [](FuzzedDataProvider* dataProvider, sp<Looper> looper, Pipe pipeObj) -> void {
+            looper->addFd(pipeObj.receiveFd, dataProvider->ConsumeIntegral<int>(),
+                          dataProvider->ConsumeIntegral<int>(), nullptr, nullptr);
+        },
+        // Events is nullptr
+        [](FuzzedDataProvider* dataProvider, sp<Looper> looper, Pipe pipeObj) -> void {
+            looper->addFd(pipeObj.receiveFd, dataProvider->ConsumeIntegral<int>(),
+                          dataProvider->ConsumeIntegral<int>(), noopCallback, nullptr);
+        },
+        // callback is nullptr
+        [](FuzzedDataProvider* dataProvider, sp<Looper> looper, Pipe pipeObj) -> void {
+            looper->addFd(pipeObj.receiveFd, dataProvider->ConsumeIntegral<int>(),
+                          dataProvider->ConsumeIntegral<int>(), nullptr, doNothingPointer);
+        },
+        // callback and events both set
+        [](FuzzedDataProvider* dataProvider, sp<Looper> looper, Pipe pipeObj) -> void {
+            looper->addFd(pipeObj.receiveFd, dataProvider->ConsumeIntegral<int>(),
+                          dataProvider->ConsumeIntegral<int>(), noopCallback, doNothingPointer);
+        },
+
+        [](FuzzedDataProvider*, sp<Looper> looper, Pipe) -> void { looper->wake(); },
+        [](FuzzedDataProvider*, sp<Looper>, Pipe pipeObj) -> void { pipeObj.writeSignal(); }};
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    Pipe pipeObj;
+    FuzzedDataProvider dataProvider(data, size);
+    sp<Looper> looper = new Looper(dataProvider.ConsumeBool());
+
+    size_t opsRun = 0;
+    while (dataProvider.remaining_bytes() > 0 && opsRun++ < MAX_OPERATIONS) {
+        uint8_t op = dataProvider.ConsumeIntegralInRange<uint8_t>(0, operations.size() - 1);
+        operations[op](&dataProvider, looper, pipeObj);
+    }
+    // Clear our pointer
+    looper.clear();
+    return 0;
+}
diff --git a/libutils/Looper_test.cpp b/libutils/Looper_test.cpp
index 37bdf05..34f424b 100644
--- a/libutils/Looper_test.cpp
+++ b/libutils/Looper_test.cpp
@@ -2,12 +2,13 @@
 // Copyright 2010 The Android Open Source Project
 //
 
-#include <utils/Looper.h>
-#include <utils/Timers.h>
-#include <utils/StopWatch.h>
 #include <gtest/gtest.h>
-#include <unistd.h>
 #include <time.h>
+#include <unistd.h>
+#include <utils/Looper.h>
+#include <utils/StopWatch.h>
+#include <utils/Timers.h>
+#include "Looper_test_pipe.h"
 
 #include <utils/threads.h>
 
@@ -24,41 +25,6 @@
     MSG_TEST4 = 4,
 };
 
-class Pipe {
-public:
-    int sendFd;
-    int receiveFd;
-
-    Pipe() {
-        int fds[2];
-        ::pipe(fds);
-
-        receiveFd = fds[0];
-        sendFd = fds[1];
-    }
-
-    ~Pipe() {
-        if (sendFd != -1) {
-            ::close(sendFd);
-        }
-
-        if (receiveFd != -1) {
-            ::close(receiveFd);
-        }
-    }
-
-    status_t writeSignal() {
-        ssize_t nWritten = ::write(sendFd, "*", 1);
-        return nWritten == 1 ? 0 : -errno;
-    }
-
-    status_t readSignal() {
-        char buf[1];
-        ssize_t nRead = ::read(receiveFd, buf, 1);
-        return nRead == 1 ? 0 : nRead == 0 ? -EPIPE : -errno;
-    }
-};
-
 class DelayedTask : public Thread {
     int mDelayMillis;
 
diff --git a/libutils/Looper_test_pipe.h b/libutils/Looper_test_pipe.h
new file mode 100644
index 0000000..77b7b8b
--- /dev/null
+++ b/libutils/Looper_test_pipe.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2020 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.
+ */
+
+#pragma once
+#include <unistd.h>
+/**
+ * A pipe class for use when testing or fuzzing Looper
+ */
+class Pipe {
+  public:
+    int sendFd;
+    int receiveFd;
+
+    Pipe() {
+        int fds[2];
+        ::pipe(fds);
+
+        receiveFd = fds[0];
+        sendFd = fds[1];
+    }
+
+    ~Pipe() {
+        if (sendFd != -1) {
+            ::close(sendFd);
+        }
+
+        if (receiveFd != -1) {
+            ::close(receiveFd);
+        }
+    }
+
+    android::status_t writeSignal() {
+        ssize_t nWritten = ::write(sendFd, "*", 1);
+        return nWritten == 1 ? 0 : -errno;
+    }
+
+    android::status_t readSignal() {
+        char buf[1];
+        ssize_t nRead = ::read(receiveFd, buf, 1);
+        return nRead == 1 ? 0 : nRead == 0 ? -EPIPE : -errno;
+    }
+};
diff --git a/libutils/LruCache_fuzz.cpp b/libutils/LruCache_fuzz.cpp
new file mode 100644
index 0000000..f8bacfc
--- /dev/null
+++ b/libutils/LruCache_fuzz.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2020 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 <functional>
+
+#include "fuzzer/FuzzedDataProvider.h"
+#include "utils/LruCache.h"
+#include "utils/StrongPointer.h"
+
+typedef android::LruCache<size_t, size_t> FuzzCache;
+
+static constexpr uint32_t MAX_CACHE_ENTRIES = 800;
+
+class NoopRemovedCallback : public android::OnEntryRemoved<size_t, size_t> {
+  public:
+    void operator()(size_t&, size_t&) {
+        // noop
+    }
+};
+
+static NoopRemovedCallback callback;
+
+static const std::vector<std::function<void(FuzzedDataProvider*, FuzzCache*)>> operations = {
+        [](FuzzedDataProvider*, FuzzCache* cache) -> void { cache->removeOldest(); },
+        [](FuzzedDataProvider*, FuzzCache* cache) -> void { cache->peekOldestValue(); },
+        [](FuzzedDataProvider*, FuzzCache* cache) -> void { cache->clear(); },
+        [](FuzzedDataProvider*, FuzzCache* cache) -> void { cache->size(); },
+        [](FuzzedDataProvider*, FuzzCache* cache) -> void {
+            android::LruCache<size_t, size_t>::Iterator iter(*cache);
+            while (iter.next()) {
+                iter.key();
+                iter.value();
+            }
+        },
+        [](FuzzedDataProvider* dataProvider, FuzzCache* cache) -> void {
+            size_t key = dataProvider->ConsumeIntegral<size_t>();
+            size_t val = dataProvider->ConsumeIntegral<size_t>();
+            cache->put(key, val);
+        },
+        [](FuzzedDataProvider* dataProvider, FuzzCache* cache) -> void {
+            size_t key = dataProvider->ConsumeIntegral<size_t>();
+            cache->get(key);
+        },
+        [](FuzzedDataProvider* dataProvider, FuzzCache* cache) -> void {
+            size_t key = dataProvider->ConsumeIntegral<size_t>();
+            cache->remove(key);
+        },
+        [](FuzzedDataProvider*, FuzzCache* cache) -> void {
+            cache->setOnEntryRemovedListener(&callback);
+        }};
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    FuzzedDataProvider dataProvider(data, size);
+    FuzzCache cache(MAX_CACHE_ENTRIES);
+    while (dataProvider.remaining_bytes() > 0) {
+        uint8_t op = dataProvider.ConsumeIntegral<uint8_t>() % operations.size();
+        operations[op](&dataProvider, &cache);
+    }
+
+    return 0;
+}
diff --git a/libutils/Printer_fuzz.cpp b/libutils/Printer_fuzz.cpp
new file mode 100755
index 0000000..0180d41
--- /dev/null
+++ b/libutils/Printer_fuzz.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2020 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 "android-base/file.h"
+#include "android/log.h"
+#include "fuzzer/FuzzedDataProvider.h"
+#include "utils/Printer.h"
+#include "utils/String8.h"
+static constexpr int MAX_STR_SIZE = 1000;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    FuzzedDataProvider dataProvider(data, size);
+    android::String8 outStr = android::String8();
+    // Line indent/formatting
+    uint indent = dataProvider.ConsumeIntegral<uint>();
+    std::string prefix = dataProvider.ConsumeRandomLengthString(MAX_STR_SIZE);
+    std::string line = dataProvider.ConsumeRandomLengthString(MAX_STR_SIZE);
+
+    // Misc properties
+    std::string logTag = dataProvider.ConsumeRandomLengthString(MAX_STR_SIZE);
+    android_LogPriority priority =
+            static_cast<android_LogPriority>(dataProvider.ConsumeIntegral<int>());
+    bool ignoreBlankLines = dataProvider.ConsumeBool();
+
+    TemporaryFile tf;
+    android::FdPrinter filePrinter = android::FdPrinter(tf.fd, indent, prefix.c_str());
+    android::String8Printer stringPrinter = android::String8Printer(&outStr);
+    android::PrefixPrinter printer = android::PrefixPrinter(stringPrinter, prefix.c_str());
+    android::LogPrinter logPrinter =
+            android::LogPrinter(logTag.c_str(), priority, prefix.c_str(), ignoreBlankLines);
+
+    printer.printLine(line.c_str());
+    printer.printFormatLine("%s", line.c_str());
+    logPrinter.printLine(line.c_str());
+    logPrinter.printFormatLine("%s", line.c_str());
+    filePrinter.printLine(line.c_str());
+    filePrinter.printFormatLine("%s", line.c_str());
+    return 0;
+}
diff --git a/libutils/ProcessCallStack_fuzz.cpp b/libutils/ProcessCallStack_fuzz.cpp
new file mode 100644
index 0000000..30136cd
--- /dev/null
+++ b/libutils/ProcessCallStack_fuzz.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2020 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 <atomic>
+#include <thread>
+
+#include "fuzzer/FuzzedDataProvider.h"
+#include "utils/ProcessCallStack.h"
+using android::ProcessCallStack;
+
+static constexpr int MAX_NAME_SIZE = 1000;
+static constexpr int MAX_LOG_META_SIZE = 1000;
+static constexpr uint8_t MAX_THREADS = 10;
+
+std::atomic_bool ranCallStackUpdate(false);
+void loop() {
+    while (!ranCallStackUpdate.load()) {
+        std::this_thread::sleep_for(std::chrono::milliseconds(50));
+    }
+}
+
+void spawnThreads(FuzzedDataProvider* dataProvider) {
+    std::vector<std::thread> threads = std::vector<std::thread>();
+
+    // Get the number of threads to generate
+    uint8_t count = dataProvider->ConsumeIntegralInRange<uint8_t>(1, MAX_THREADS);
+
+    // Generate threads
+    for (uint8_t i = 0; i < count; i++) {
+        std::string threadName =
+                dataProvider->ConsumeRandomLengthString(MAX_NAME_SIZE).append(std::to_string(i));
+        std::thread th = std::thread(loop);
+        pthread_setname_np(th.native_handle(), threadName.c_str());
+        threads.push_back(move(th));
+    }
+
+    // Collect thread information
+    ProcessCallStack callStack = ProcessCallStack();
+    callStack.update();
+
+    // Tell our patiently waiting threads they can be done now.
+    ranCallStackUpdate.store(true);
+
+    std::string logTag = dataProvider->ConsumeRandomLengthString(MAX_LOG_META_SIZE);
+    std::string prefix = dataProvider->ConsumeRandomLengthString(MAX_LOG_META_SIZE);
+    // Both of these, along with dump, all call print() under the hood,
+    // Which is covered by the Printer fuzzer.
+    callStack.log(logTag.c_str());
+    callStack.toString(prefix.c_str());
+
+    // Check size
+    callStack.size();
+
+    // wait for any remaining threads
+    for (auto& thread : threads) {
+        thread.join();
+    }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    FuzzedDataProvider dataProvider(data, size);
+    spawnThreads(&dataProvider);
+    return 0;
+}
diff --git a/libutils/PropertyMap_fuzz.cpp b/libutils/PropertyMap_fuzz.cpp
new file mode 100755
index 0000000..fd50729
--- /dev/null
+++ b/libutils/PropertyMap_fuzz.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2020 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 "android-base/file.h"
+#include "fuzzer/FuzzedDataProvider.h"
+#include "utils/PropertyMap.h"
+#include "utils/String8.h"
+
+static constexpr int MAX_FILE_SIZE = 256;
+static constexpr int MAX_STR_LEN = 2048;
+static constexpr int MAX_OPERATIONS = 1000;
+
+static const std::vector<std::function<void(FuzzedDataProvider*, android::PropertyMap)>>
+        operations = {
+                [](FuzzedDataProvider*, android::PropertyMap propertyMap) -> void {
+                    propertyMap.getProperties();
+                },
+                [](FuzzedDataProvider*, android::PropertyMap propertyMap) -> void {
+                    propertyMap.clear();
+                },
+                [](FuzzedDataProvider* dataProvider, android::PropertyMap propertyMap) -> void {
+                    std::string keyStr = dataProvider->ConsumeRandomLengthString(MAX_STR_LEN);
+                    android::String8 key = android::String8(keyStr.c_str());
+                    propertyMap.hasProperty(key);
+                },
+                [](FuzzedDataProvider* dataProvider, android::PropertyMap propertyMap) -> void {
+                    std::string keyStr = dataProvider->ConsumeRandomLengthString(MAX_STR_LEN);
+                    android::String8 key = android::String8(keyStr.c_str());
+                    android::String8 out;
+                    propertyMap.tryGetProperty(key, out);
+                },
+                [](FuzzedDataProvider* dataProvider, android::PropertyMap propertyMap) -> void {
+                    TemporaryFile tf;
+                    // Generate file contents
+                    std::string contents = dataProvider->ConsumeRandomLengthString(MAX_FILE_SIZE);
+                    // If we have string contents, dump them into the file.
+                    // Otherwise, just leave it as an empty file.
+                    if (contents.length() > 0) {
+                        const char* bytes = contents.c_str();
+                        android::base::WriteStringToFd(bytes, tf.fd);
+                    }
+                    android::PropertyMap* mapPtr = &propertyMap;
+                    android::PropertyMap::load(android::String8(tf.path), &mapPtr);
+                },
+                [](FuzzedDataProvider* dataProvider, android::PropertyMap propertyMap) -> void {
+                    std::string keyStr = dataProvider->ConsumeRandomLengthString(MAX_STR_LEN);
+                    std::string valStr = dataProvider->ConsumeRandomLengthString(MAX_STR_LEN);
+                    android::String8 key = android::String8(keyStr.c_str());
+                    android::String8 val = android::String8(valStr.c_str());
+                    propertyMap.addProperty(key, val);
+                },
+};
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    FuzzedDataProvider dataProvider(data, size);
+    android::PropertyMap proprtyMap = android::PropertyMap();
+
+    int opsRun = 0;
+    while (dataProvider.remaining_bytes() > 0 && opsRun++ < MAX_OPERATIONS) {
+        uint8_t op = dataProvider.ConsumeIntegralInRange<uint8_t>(0, operations.size() - 1);
+        operations[op](&dataProvider, proprtyMap);
+    }
+    return 0;
+}
diff --git a/libutils/RWLock_fuzz.cpp b/libutils/RWLock_fuzz.cpp
new file mode 100755
index 0000000..e075905
--- /dev/null
+++ b/libutils/RWLock_fuzz.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2020 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 <functional>
+
+#include "fuzzer/FuzzedDataProvider.h"
+#include "utils/RWLock.h"
+
+static constexpr int MAX_OPERATIONS = 100;
+static constexpr int MAX_NAME_LEN = 2048;
+
+static const std::vector<std::function<void(android::RWLock*)>> operations = {
+        [](android::RWLock* lock) -> void {
+            // This might return a non-zero value if already locked
+            // Either way we are definitely locked now.
+            lock->tryWriteLock();
+        },
+        [](android::RWLock* lock) -> void { lock->tryReadLock(); },
+        [](android::RWLock* lock) -> void { lock->unlock(); },
+};
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    FuzzedDataProvider dataProvider(data, size);
+    std::string nameStr = dataProvider.ConsumeRandomLengthString(MAX_NAME_LEN);
+    int type = dataProvider.ConsumeIntegral<int>();
+    android::RWLock rwLock = android::RWLock(type, nameStr.c_str());
+    std::vector<uint8_t> opsToRun = dataProvider.ConsumeRemainingBytes<uint8_t>();
+    int opsRun = 0;
+    for (auto it : opsToRun) {
+        if (opsRun++ >= MAX_OPERATIONS) {
+            break;
+        }
+        it = it % operations.size();
+        operations[it](&rwLock);
+    }
+    rwLock.unlock();
+    return 0;
+}
diff --git a/libutils/RefBase_fuzz.cpp b/libutils/RefBase_fuzz.cpp
new file mode 100755
index 0000000..2a92531
--- /dev/null
+++ b/libutils/RefBase_fuzz.cpp
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2020 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 <atomic>
+#include <thread>
+
+#include "fuzzer/FuzzedDataProvider.h"
+#include "utils/RefBase.h"
+#include "utils/StrongPointer.h"
+using android::RefBase;
+using android::sp;
+using android::wp;
+
+static constexpr int REFBASE_INITIAL_STRONG_VALUE = (1 << 28);
+static constexpr int REFBASE_MAX_COUNT = 0xfffff;
+
+static constexpr int MAX_OPERATIONS = 100;
+static constexpr int MAX_THREADS = 10;
+
+bool canDecrementStrong(RefBase* ref) {
+    // There's an assert around decrementing the strong count too much that causes an artificial
+    // crash This is just running BAD_STRONG from RefBase
+    const int32_t count = ref->getStrongCount() - 1;
+    return !(count == 0 || ((count) & (~(REFBASE_MAX_COUNT | REFBASE_INITIAL_STRONG_VALUE))) != 0);
+}
+bool canDecrementWeak(RefBase* ref) {
+    const int32_t count = ref->getWeakRefs()->getWeakCount() - 1;
+    return !((count) == 0 || ((count) & (~REFBASE_MAX_COUNT)) != 0);
+}
+
+struct RefBaseSubclass : public RefBase {
+    RefBaseSubclass() {}
+    virtual ~RefBaseSubclass() {}
+};
+
+std::vector<std::function<void(RefBaseSubclass*)>> operations = {
+        [](RefBaseSubclass* ref) -> void { ref->getStrongCount(); },
+        [](RefBaseSubclass* ref) -> void { ref->printRefs(); },
+        [](RefBaseSubclass* ref) -> void { ref->getWeakRefs()->printRefs(); },
+        [](RefBaseSubclass* ref) -> void { ref->getWeakRefs()->getWeakCount(); },
+        [](RefBaseSubclass* ref) -> void { ref->getWeakRefs()->refBase(); },
+        [](RefBaseSubclass* ref) -> void { ref->incStrong(nullptr); },
+        [](RefBaseSubclass* ref) -> void {
+            if (canDecrementStrong(ref)) {
+                ref->decStrong(nullptr);
+            }
+        },
+        [](RefBaseSubclass* ref) -> void { ref->forceIncStrong(nullptr); },
+        [](RefBaseSubclass* ref) -> void { ref->createWeak(nullptr); },
+        [](RefBaseSubclass* ref) -> void { ref->getWeakRefs()->attemptIncStrong(nullptr); },
+        [](RefBaseSubclass* ref) -> void { ref->getWeakRefs()->attemptIncWeak(nullptr); },
+        [](RefBaseSubclass* ref) -> void {
+            if (canDecrementWeak(ref)) {
+                ref->getWeakRefs()->decWeak(nullptr);
+            }
+        },
+        [](RefBaseSubclass* ref) -> void { ref->getWeakRefs()->incWeak(nullptr); },
+        [](RefBaseSubclass* ref) -> void { ref->getWeakRefs()->printRefs(); },
+};
+
+void loop(RefBaseSubclass* loopRef, const std::vector<uint8_t>& fuzzOps) {
+    for (auto op : fuzzOps) {
+        operations[op % operations.size()](loopRef);
+    }
+}
+
+void spawnThreads(FuzzedDataProvider* dataProvider) {
+    std::vector<std::thread> threads = std::vector<std::thread>();
+
+    // Get the number of threads to generate
+    uint8_t count = dataProvider->ConsumeIntegralInRange<uint8_t>(1, MAX_THREADS);
+
+    // Generate threads
+    for (uint8_t i = 0; i < count; i++) {
+        RefBaseSubclass* threadRef = new RefBaseSubclass();
+        uint8_t opCount = dataProvider->ConsumeIntegralInRange<uint8_t>(1, MAX_OPERATIONS);
+        std::vector<uint8_t> threadOperations = dataProvider->ConsumeBytes<uint8_t>(opCount);
+        std::thread tmp = std::thread(loop, threadRef, threadOperations);
+        threads.push_back(move(tmp));
+    }
+
+    for (auto& th : threads) {
+        th.join();
+    }
+}
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    FuzzedDataProvider dataProvider(data, size);
+    spawnThreads(&dataProvider);
+    return 0;
+}
diff --git a/libutils/StopWatch_fuzz.cpp b/libutils/StopWatch_fuzz.cpp
new file mode 100644
index 0000000..63d8a28
--- /dev/null
+++ b/libutils/StopWatch_fuzz.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2020 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 "utils/StopWatch.h"
+
+static constexpr int MAX_OPERATIONS = 100;
+static constexpr int MAX_NAME_LEN = 2048;
+
+static const std::vector<std::function<void(android::StopWatch)>> operations = {
+        [](android::StopWatch stopWatch) -> void { stopWatch.reset(); },
+        [](android::StopWatch stopWatch) -> void { stopWatch.lap(); },
+        [](android::StopWatch stopWatch) -> void { stopWatch.elapsedTime(); },
+        [](android::StopWatch stopWatch) -> void { stopWatch.name(); },
+};
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    FuzzedDataProvider dataProvider(data, size);
+    std::string nameStr = dataProvider.ConsumeRandomLengthString(MAX_NAME_LEN);
+    int clockVal = dataProvider.ConsumeIntegral<int>();
+    android::StopWatch stopWatch = android::StopWatch(nameStr.c_str(), clockVal);
+    std::vector<uint8_t> opsToRun = dataProvider.ConsumeRemainingBytes<uint8_t>();
+    int opsRun = 0;
+    for (auto it : opsToRun) {
+        if (opsRun++ >= MAX_OPERATIONS) {
+            break;
+        }
+        it = it % operations.size();
+        operations[it](stopWatch);
+    }
+    return 0;
+}