Merge "Add second batch of fuzzers for libutils" am: 2cfea97ba3
am: 354d814409
am: 20fc570cd2
am: f5d5edbb8d
Original change: https://android-review.googlesource.com/c/platform/system/core/+/1356122 Change-Id: I9bc1a713a7e31a26c653d78cc503671c57d0927a
This commit is contained in:
commit
ec11814f57
12 changed files with 732 additions and 39 deletions
|
@ -205,6 +205,7 @@ cc_defaults {
|
|||
shared_libs: [
|
||||
"libutils",
|
||||
"libbase",
|
||||
"liblog",
|
||||
],
|
||||
}
|
||||
|
||||
|
@ -238,6 +239,66 @@ cc_fuzz {
|
|||
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,
|
||||
|
|
50
libutils/CallStack_fuzz.cpp
Normal file
50
libutils/CallStack_fuzz.cpp
Normal file
|
@ -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;
|
||||
}
|
84
libutils/Looper_fuzz.cpp
Normal file
84
libutils/Looper_fuzz.cpp
Normal file
|
@ -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;
|
||||
}
|
|
@ -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 @@ enum {
|
|||
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;
|
||||
|
||||
|
|
55
libutils/Looper_test_pipe.h
Normal file
55
libutils/Looper_test_pipe.h
Normal file
|
@ -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;
|
||||
}
|
||||
};
|
74
libutils/LruCache_fuzz.cpp
Normal file
74
libutils/LruCache_fuzz.cpp
Normal file
|
@ -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;
|
||||
}
|
52
libutils/Printer_fuzz.cpp
Executable file
52
libutils/Printer_fuzz.cpp
Executable file
|
@ -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;
|
||||
}
|
77
libutils/ProcessCallStack_fuzz.cpp
Normal file
77
libutils/ProcessCallStack_fuzz.cpp
Normal file
|
@ -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;
|
||||
}
|
76
libutils/PropertyMap_fuzz.cpp
Executable file
76
libutils/PropertyMap_fuzz.cpp
Executable file
|
@ -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;
|
||||
}
|
50
libutils/RWLock_fuzz.cpp
Executable file
50
libutils/RWLock_fuzz.cpp
Executable file
|
@ -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;
|
||||
}
|
103
libutils/RefBase_fuzz.cpp
Executable file
103
libutils/RefBase_fuzz.cpp
Executable file
|
@ -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;
|
||||
}
|
45
libutils/StopWatch_fuzz.cpp
Normal file
45
libutils/StopWatch_fuzz.cpp
Normal file
|
@ -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;
|
||||
}
|
Loading…
Reference in a new issue