Merge "Add second batch of fuzzers for libutils"
This commit is contained in:
commit
2cfea97ba3
12 changed files with 732 additions and 39 deletions
|
|
@ -205,6 +205,7 @@ cc_defaults {
|
||||||
shared_libs: [
|
shared_libs: [
|
||||||
"libutils",
|
"libutils",
|
||||||
"libbase",
|
"libbase",
|
||||||
|
"liblog",
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -238,6 +239,66 @@ cc_fuzz {
|
||||||
srcs: ["Vector_fuzz.cpp"],
|
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 {
|
cc_test {
|
||||||
name: "libutils_test",
|
name: "libutils_test",
|
||||||
host_supported: true,
|
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
|
// Copyright 2010 The Android Open Source Project
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <utils/Looper.h>
|
|
||||||
#include <utils/Timers.h>
|
|
||||||
#include <utils/StopWatch.h>
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <time.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>
|
#include <utils/threads.h>
|
||||||
|
|
||||||
|
|
@ -24,41 +25,6 @@ enum {
|
||||||
MSG_TEST4 = 4,
|
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 {
|
class DelayedTask : public Thread {
|
||||||
int mDelayMillis;
|
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…
Add table
Reference in a new issue