diff options
| -rw-r--r-- | PREUPLOAD.cfg | 1 | ||||
| -rw-r--r-- | libs/binder/tests/fuzzers/Android.bp | 66 | ||||
| -rw-r--r-- | libs/binder/tests/fuzzers/BinderFuzz.cpp | 46 | ||||
| -rw-r--r-- | libs/binder/tests/fuzzers/BinderFuzzFunctions.h | 70 | ||||
| -rw-r--r-- | libs/binder/tests/fuzzers/BpBinderFuzz.cpp | 54 | ||||
| -rw-r--r-- | libs/binder/tests/fuzzers/BpBinderFuzzFunctions.h | 110 | ||||
| -rw-r--r-- | libs/binder/tests/fuzzers/IBinderFuzzFunctions.h | 87 | ||||
| -rw-r--r-- | libs/binder/tests/fuzzers/PersistableBundleFuzz.cpp | 37 | ||||
| -rw-r--r-- | libs/binder/tests/fuzzers/PersistableBundleFuzzFunctions.h | 183 | ||||
| -rw-r--r-- | libs/binder/tests/fuzzers/StabilityFuzz.cpp | 33 | ||||
| -rw-r--r-- | libs/binder/tests/fuzzers/StabilityFuzzFunctions.h | 67 | ||||
| -rw-r--r-- | libs/binder/tests/fuzzers/StatusFuzz.cpp | 47 | ||||
| -rw-r--r-- | libs/binder/tests/fuzzers/StatusFuzzFunctions.h | 91 | ||||
| -rw-r--r-- | libs/binder/tests/fuzzers/TextOutputFuzz.cpp | 60 | ||||
| -rw-r--r-- | libs/binder/tests/fuzzers/commonFuzzHelpers.h | 41 |
15 files changed, 993 insertions, 0 deletions
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg index 0473bb833e..9cab9b4c41 100644 --- a/PREUPLOAD.cfg +++ b/PREUPLOAD.cfg @@ -8,6 +8,7 @@ clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp include/input/ libs/binder/fuzzer/ libs/binder/ndk/ + libs/binder/tests/fuzzers/ libs/binderthreadstate/ libs/graphicsenv/ libs/gui/ diff --git a/libs/binder/tests/fuzzers/Android.bp b/libs/binder/tests/fuzzers/Android.bp new file mode 100644 index 0000000000..46379fc629 --- /dev/null +++ b/libs/binder/tests/fuzzers/Android.bp @@ -0,0 +1,66 @@ +// +// Copyright (C) 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. +// + +cc_defaults { + name: "binder_fuzz_defaults", + host_supported: true, + cflags: [ + "-Wall", + "-Werror", + ], + shared_libs: [ + "libbinder", + "libutils", + "libbase", + ], +} + +cc_fuzz { + name: "binder_binderFuzz", + defaults: ["binder_fuzz_defaults"], + srcs: ["BinderFuzz.cpp"], +} + +cc_fuzz { + name: "binder_bpBinderFuzz", + defaults: ["binder_fuzz_defaults"], + host_supported: false, + srcs: ["BpBinderFuzz.cpp"], +} + +cc_fuzz { + name: "binder_persistableBundleFuzz", + defaults: ["binder_fuzz_defaults"], + srcs: ["PersistableBundleFuzz.cpp"], +} + +cc_fuzz { + name: "binder_stabilityFuzz", + defaults: ["binder_fuzz_defaults"], + srcs: ["StabilityFuzz.cpp"], +} + +cc_fuzz { + name: "binder_statusFuzz", + defaults: ["binder_fuzz_defaults"], + srcs: ["StatusFuzz.cpp"], +} + +cc_fuzz { + name: "binder_textOutputFuzz", + defaults: ["binder_fuzz_defaults"], + srcs: ["TextOutputFuzz.cpp"], +} diff --git a/libs/binder/tests/fuzzers/BinderFuzz.cpp b/libs/binder/tests/fuzzers/BinderFuzz.cpp new file mode 100644 index 0000000000..1e5d80a205 --- /dev/null +++ b/libs/binder/tests/fuzzers/BinderFuzz.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 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 <BinderFuzzFunctions.h> +#include <IBinderFuzzFunctions.h> +#include <commonFuzzHelpers.h> +#include <fuzzer/FuzzedDataProvider.h> + +#include <binder/Binder.h> + +namespace android { + +// Fuzzer entry point. +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + FuzzedDataProvider fdp(data, size); + sp<BBinder> bbinder = new BBinder(); + + // To prevent memory from running out from calling too many add item operations. + const uint32_t MAX_RUNS = 2048; + uint32_t count = 0; + + while (fdp.remaining_bytes() > 0 && count++ < MAX_RUNS) { + if (fdp.ConsumeBool()) { + callArbitraryFunction(&fdp, gBBinderOperations, bbinder); + } else { + callArbitraryFunction(&fdp, gIBinderOperations, + reinterpret_cast<IBinder *>(bbinder.get())); + } + } + + return 0; +} +} // namespace android diff --git a/libs/binder/tests/fuzzers/BinderFuzzFunctions.h b/libs/binder/tests/fuzzers/BinderFuzzFunctions.h new file mode 100644 index 0000000000..9ac65bb2c1 --- /dev/null +++ b/libs/binder/tests/fuzzers/BinderFuzzFunctions.h @@ -0,0 +1,70 @@ +/* + * 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 <IBinderFuzzFunctions.h> +#include <fuzzer/FuzzedDataProvider.h> + +#include <binder/Binder.h> +#include <binder/IBinder.h> +#include <binder/Parcel.h> +#include <stdint.h> +#include <atomic> + +namespace android { + +/* This is a vector of lambda functions the fuzzer will pull from. + * This is done so new functions can be added to the fuzzer easily + * without requiring modifications to the main fuzzer file. This also + * allows multiple fuzzers to include this file, if functionality is needed. + */ +static const std::vector<std::function<void(FuzzedDataProvider*, const sp<BBinder>&)>> + gBBinderOperations = {[](FuzzedDataProvider*, const sp<BBinder>& bbinder) -> void { + bbinder->isRequestingSid(); + }, + [](FuzzedDataProvider* fdp, const sp<BBinder>& bbinder) -> void { + bool request_sid = fdp->ConsumeBool(); + bbinder->setRequestingSid(request_sid); + }, + [](FuzzedDataProvider*, const sp<BBinder>& bbinder) -> void { + bbinder->getExtension(); + }, + [](FuzzedDataProvider*, const sp<BBinder>& bbinder) -> void { + static IBinder* extension = nullptr; + bbinder->setExtension(extension); + }, + [](FuzzedDataProvider* fdp, const sp<BBinder>& bbinder) -> void { + int priority; + int policy = fdp->ConsumeIntegralInRange<int>(0, 2); + if (policy == 0) { + priority = fdp->ConsumeIntegralInRange<int>(-20, 19); + } else { + priority = fdp->ConsumeIntegralInRange<int>(1, 99); + } + bbinder->setMinSchedulerPolicy(policy, priority); + }, + [](FuzzedDataProvider*, const sp<BBinder>& bbinder) -> void { + bbinder->getMinSchedulerPolicy(); + }, + [](FuzzedDataProvider*, const sp<BBinder>& bbinder) -> void { + bbinder->getMinSchedulerPriority(); + }, + [](FuzzedDataProvider*, const sp<BBinder>& bbinder) -> void { + bbinder->getDebugPid(); + }}; + +} // namespace android diff --git a/libs/binder/tests/fuzzers/BpBinderFuzz.cpp b/libs/binder/tests/fuzzers/BpBinderFuzz.cpp new file mode 100644 index 0000000000..c50279b13d --- /dev/null +++ b/libs/binder/tests/fuzzers/BpBinderFuzz.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 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 <BpBinderFuzzFunctions.h> +#include <IBinderFuzzFunctions.h> +#include <commonFuzzHelpers.h> +#include <fuzzer/FuzzedDataProvider.h> + +#include <binder/BpBinder.h> +#include <binder/IServiceManager.h> + +namespace android { + +// Fuzzer entry point. +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + FuzzedDataProvider fdp(data, size); + + // TODO: In the future it would be more effective to fork a new process and then pass a BBinder + // to your process. Right now this is not implemented because it would involved fuzzing IPC on a + // forked process, and libfuzzer will not be able to handle code coverage. This would lead to + // crashes that are not easy to diagnose. + int32_t handle = fdp.ConsumeIntegralInRange<int32_t>(0, 1024); + sp<BpBinder> bpbinder = BpBinder::create(handle); + if (bpbinder == nullptr) return 0; + + // To prevent memory from running out from calling too many add item operations. + const uint32_t MAX_RUNS = 2048; + uint32_t count = 0; + sp<IBinder::DeathRecipient> s_recipient = new FuzzDeathRecipient(); + + while (fdp.remaining_bytes() > 0 && count++ < MAX_RUNS) { + if (fdp.ConsumeBool()) { + callArbitraryFunction(&fdp, gBPBinderOperations, bpbinder, s_recipient); + } else { + callArbitraryFunction(&fdp, gIBinderOperations, bpbinder.get()); + } + } + + return 0; +} +} // namespace android diff --git a/libs/binder/tests/fuzzers/BpBinderFuzzFunctions.h b/libs/binder/tests/fuzzers/BpBinderFuzzFunctions.h new file mode 100644 index 0000000000..c685b41026 --- /dev/null +++ b/libs/binder/tests/fuzzers/BpBinderFuzzFunctions.h @@ -0,0 +1,110 @@ +/* + * 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 <IBinderFuzzFunctions.h> +#include <fuzzer/FuzzedDataProvider.h> + +#include <binder/BpBinder.h> +#include <binder/IBinder.h> +#include <binder/IPCThreadState.h> +#include <binder/IResultReceiver.h> +#include <binder/Parcel.h> +#include <binder/Stability.h> + +#include <cutils/compiler.h> +#include <utils/KeyedVector.h> +#include <utils/Log.h> +#include <utils/Mutex.h> +#include <utils/threads.h> + +#include <stdio.h> + +namespace android { + +// Static variable to reference so we don't consume a bunch of memory to link and +// unlink DeathRecipients. +static int8_t kBpBinderCookie = 0; + +/* This is a vector of lambda functions the fuzzer will pull from. + * This is done so new functions can be added to the fuzzer easily + * without requiring modifications to the main fuzzer file. This also + * allows multiple fuzzers to include this file, if functionality is needed. + */ +static const std::vector<std::function<void(FuzzedDataProvider*, const sp<BpBinder>&, + const sp<IBinder::DeathRecipient>&)>> + gBPBinderOperations = + {[](FuzzedDataProvider*, const sp<BpBinder>& bpbinder, + const sp<IBinder::DeathRecipient>&) -> void { bpbinder->handle(); }, + [](FuzzedDataProvider* fdp, const sp<BpBinder>& bpbinder, + const sp<IBinder::DeathRecipient>& s_recipient) -> void { + // Clean up possible leftover memory. + wp<IBinder::DeathRecipient> outRecipient(nullptr); + bpbinder->sendObituary(); + bpbinder->unlinkToDeath(nullptr, reinterpret_cast<void*>(&kBpBinderCookie), 0, + &outRecipient); + + uint32_t flags = fdp->ConsumeIntegral<uint32_t>(); + kBpBinderCookie = fdp->ConsumeIntegral<int8_t>(); + bpbinder->linkToDeath(s_recipient.get(), + reinterpret_cast<void*>(&kBpBinderCookie), flags); + }, + [](FuzzedDataProvider* fdp, const sp<BpBinder>& bpbinder, + const sp<IBinder::DeathRecipient>&) -> void { + wp<IBinder::DeathRecipient> out_recipient(nullptr); + uint32_t flags = fdp->ConsumeIntegral<uint32_t>(); + int8_t random_cookie = fdp->ConsumeIntegral<int8_t>(); + bpbinder->unlinkToDeath(nullptr, reinterpret_cast<void*>(&random_cookie), + flags, &out_recipient); + }, + [](FuzzedDataProvider*, const sp<BpBinder>& bpbinder, + const sp<IBinder::DeathRecipient>&) -> void { bpbinder->remoteBinder(); }, + [](FuzzedDataProvider*, const sp<BpBinder>& bpbinder, + const sp<IBinder::DeathRecipient>&) -> void { bpbinder->sendObituary(); }, + [](FuzzedDataProvider* fdp, const sp<BpBinder>& bpbinder, + const sp<IBinder::DeathRecipient>&) -> void { + uint32_t uid = fdp->ConsumeIntegral<uint32_t>(); + bpbinder->getBinderProxyCount(uid); + }, + [](FuzzedDataProvider*, const sp<BpBinder>& bpbinder, + const sp<IBinder::DeathRecipient>&) -> void { bpbinder->enableCountByUid(); }, + [](FuzzedDataProvider*, const sp<BpBinder>& bpbinder, + const sp<IBinder::DeathRecipient>&) -> void { bpbinder->disableCountByUid(); }, + [](FuzzedDataProvider*, const sp<BpBinder>& bpbinder, + const sp<IBinder::DeathRecipient>&) -> void { + Vector<uint32_t> uids; + Vector<uint32_t> counts; + bpbinder->getCountByUid(uids, counts); + }, + [](FuzzedDataProvider* fdp, const sp<BpBinder>& bpbinder, + const sp<IBinder::DeathRecipient>&) -> void { + bool enable = fdp->ConsumeBool(); + bpbinder->setCountByUidEnabled(enable); + }, + [](FuzzedDataProvider*, const sp<BpBinder>& bpbinder, + const sp<IBinder::DeathRecipient>&) -> void { + binder_proxy_limit_callback cb = binder_proxy_limit_callback(); + bpbinder->setLimitCallback(cb); + }, + [](FuzzedDataProvider* fdp, const sp<BpBinder>& bpbinder, + const sp<IBinder::DeathRecipient>&) -> void { + int high = fdp->ConsumeIntegral<int>(); + int low = fdp->ConsumeIntegral<int>(); + bpbinder->setBinderProxyCountWatermarks(high, low); + }}; + +} // namespace android diff --git a/libs/binder/tests/fuzzers/IBinderFuzzFunctions.h b/libs/binder/tests/fuzzers/IBinderFuzzFunctions.h new file mode 100644 index 0000000000..626b7585f7 --- /dev/null +++ b/libs/binder/tests/fuzzers/IBinderFuzzFunctions.h @@ -0,0 +1,87 @@ +/* + * 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 <fuzzer/FuzzedDataProvider.h> + +#include <binder/IBinder.h> +#include <binder/IPCThreadState.h> +#include <binder/IResultReceiver.h> +#include <binder/Parcel.h> +#include <binder/Stability.h> +#include <cutils/compiler.h> +#include <utils/KeyedVector.h> +#include <utils/Log.h> +#include <utils/Mutex.h> +#include <utils/threads.h> + +namespace android { + +class FuzzDeathRecipient : public IBinder::DeathRecipient { +private: + virtual void binderDied(const wp<IBinder>& who) { (void)who; }; +}; + +// Allow objects to be attached that aren't stack locals +static uint32_t objectID = 0; +static uint32_t object = 0; +static uint32_t cleanup_cookie = 0; + +/* This is a vector of lambda functions the fuzzer will pull from. + * This is done so new functions can be added to the fuzzer easily + * without requiring modifications to the main fuzzer file. This also + * allows multiple fuzzers to include this file, if functionality is needed. + */ +static const std::vector<std::function<void(FuzzedDataProvider*, IBinder*)>> gIBinderOperations = + {[](FuzzedDataProvider*, IBinder* ibinder) -> void { ibinder->getInterfaceDescriptor(); }, + [](FuzzedDataProvider*, IBinder* ibinder) -> void { ibinder->isBinderAlive(); }, + [](FuzzedDataProvider*, IBinder* ibinder) -> void { ibinder->pingBinder(); }, + [](FuzzedDataProvider* fdp, IBinder* ibinder) -> void { + int fd = STDOUT_FILENO; + std::string rand_str = fdp->ConsumeRandomLengthString(fdp->remaining_bytes()); + Vector<String16> args; + args.push(String16(rand_str.c_str())); + ibinder->dump(fd, args); + }, + [](FuzzedDataProvider* fdp, IBinder* ibinder) -> void { + objectID = fdp->ConsumeIntegral<uint32_t>(); + object = fdp->ConsumeIntegral<uint32_t>(); + cleanup_cookie = fdp->ConsumeIntegral<uint32_t>(); + IBinder::object_cleanup_func func = IBinder::object_cleanup_func(); + ibinder->attachObject(fdp->ConsumeBool() ? reinterpret_cast<void*>(&objectID) + : nullptr, + fdp->ConsumeBool() ? reinterpret_cast<void*>(&object) : nullptr, + fdp->ConsumeBool() ? reinterpret_cast<void*>(&cleanup_cookie) + : nullptr, + func); + }, + [](FuzzedDataProvider* fdp, IBinder* ibinder) -> void { + uint32_t id = fdp->ConsumeIntegral<uint32_t>(); + ibinder->findObject(reinterpret_cast<void*>(&id)); + }, + [](FuzzedDataProvider* fdp, IBinder* ibinder) -> void { + uint32_t id = fdp->ConsumeIntegral<uint32_t>(); + ibinder->detachObject(reinterpret_cast<void*>(&id)); + }, + [](FuzzedDataProvider* fdp, IBinder* ibinder) -> void { + uint32_t code = fdp->ConsumeIntegral<uint32_t>(); + Parcel p_data; + Parcel reply; + uint32_t flags = fdp->ConsumeIntegral<uint32_t>(); + ibinder->transact(code, p_data, &reply, flags); + }}; +} // namespace android diff --git a/libs/binder/tests/fuzzers/PersistableBundleFuzz.cpp b/libs/binder/tests/fuzzers/PersistableBundleFuzz.cpp new file mode 100644 index 0000000000..4843c46545 --- /dev/null +++ b/libs/binder/tests/fuzzers/PersistableBundleFuzz.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 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 <PersistableBundleFuzzFunctions.h> +#include <binder/PersistableBundle.h> +#include <commonFuzzHelpers.h> +#include <fuzzer/FuzzedDataProvider.h> +#include <utils/String16.h> + +namespace android { +// Fuzzer entry point. +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + FuzzedDataProvider fdp(data, size); + std::shared_ptr<os::PersistableBundle> p_bundle(new os::PersistableBundle()); + + while (fdp.remaining_bytes() > 0) { + String16 key(fdp.ConsumeRandomLengthString(fdp.remaining_bytes()).c_str()); + callArbitraryFunction(&fdp, gPersistableBundleOperations, p_bundle, &key); + } + + return 0; +} + +} // namespace android diff --git a/libs/binder/tests/fuzzers/PersistableBundleFuzzFunctions.h b/libs/binder/tests/fuzzers/PersistableBundleFuzzFunctions.h new file mode 100644 index 0000000000..820e9e8c31 --- /dev/null +++ b/libs/binder/tests/fuzzers/PersistableBundleFuzzFunctions.h @@ -0,0 +1,183 @@ +/* + * 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 <binder/Parcel.h> +#include <binder/Parcelable.h> +#include <binder/PersistableBundle.h> +#include <fuzzer/FuzzedDataProvider.h> +#include <utils/String16.h> +#include <utils/StrongPointer.h> +#include <map> +#include <set> +#include <vector> + +namespace android { + +/* This is a vector of lambda functions the fuzzer will pull from. + * This is done so new functions can be added to the fuzzer easily + * without requiring modifications to the main fuzzer file. This also + * allows multiple fuzzers to include this file, if functionality is needed. + */ +static const std::vector<std::function< + void(FuzzedDataProvider*, std::shared_ptr<os::PersistableBundle> const&, String16*)>> + gPersistableBundleOperations = + {[](FuzzedDataProvider*, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16*) -> void { p_bundle->empty(); }, + [](FuzzedDataProvider*, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16*) -> void { + Parcel parcel; + p_bundle->writeToParcel(&parcel); + }, + [](FuzzedDataProvider* fdp, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16*) -> void { + Parcel parcel; + std::vector<uint8_t> buf = fdp->ConsumeBytes<uint8_t>( + fdp->ConsumeIntegralInRange<size_t>(0, fdp->remaining_bytes() - 1)); + parcel.write(buf.data(), buf.size()); + p_bundle->readFromParcel(&parcel); + }, + [](FuzzedDataProvider*, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16*) -> void { p_bundle->size(); }, + [](FuzzedDataProvider*, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16* key) -> void { p_bundle->erase(*key); }, + [](FuzzedDataProvider* fdp, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16* key) -> void { + bool value = fdp->ConsumeBool(); + p_bundle->putBoolean(*key, value); + }, + [](FuzzedDataProvider* fdp, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16* key) -> void { + int32_t value = fdp->ConsumeIntegral<int32_t>(); + p_bundle->putInt(*key, value); + }, + [](FuzzedDataProvider*, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16* key) -> void { + os::PersistableBundle value = os::PersistableBundle(); + p_bundle->putPersistableBundle(*key, value); + }, + [](FuzzedDataProvider*, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16* key) -> void { + std::vector<String16> value; + p_bundle->putStringVector(*key, value); + }, + [](FuzzedDataProvider*, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16* key) -> void { + std::vector<double> value; + p_bundle->putDoubleVector(*key, value); + }, + [](FuzzedDataProvider*, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16* key) -> void { + std::vector<int64_t> value; + p_bundle->putLongVector(*key, value); + }, + [](FuzzedDataProvider*, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16* key) -> void { + std::vector<int32_t> value; + p_bundle->putIntVector(*key, value); + }, + [](FuzzedDataProvider*, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16* key) -> void { + std::vector<bool> value; + p_bundle->putBooleanVector(*key, value); + }, + [](FuzzedDataProvider* fdp, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16* key) -> void { + String16 value(fdp->ConsumeRandomLengthString(fdp->remaining_bytes()).c_str()); + p_bundle->putString(*key, value); + }, + [](FuzzedDataProvider* fdp, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16* key) -> void { + int64_t value = fdp->ConsumeIntegral<int64_t>(); + p_bundle->putLong(*key, value); + }, + [](FuzzedDataProvider* fdp, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16* key) -> void { + double value = fdp->ConsumeFloatingPoint<double>(); + p_bundle->putDouble(*key, value); + }, + [](FuzzedDataProvider*, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16* key) -> void { + bool out; + p_bundle->getBoolean(*key, &out); + }, + [](FuzzedDataProvider*, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16* key) -> void { + os::PersistableBundle out; + p_bundle->getPersistableBundle(*key, &out); + }, + [](FuzzedDataProvider*, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16* key) -> void { + std::vector<String16> out; + p_bundle->getStringVector(*key, &out); + }, + [](FuzzedDataProvider*, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16* key) -> void { + std::vector<double> out; + p_bundle->getDoubleVector(*key, &out); + }, + [](FuzzedDataProvider*, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16* key) -> void { + std::vector<int64_t> out; + p_bundle->getLongVector(*key, &out); + }, + [](FuzzedDataProvider*, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16* key) -> void { + std::vector<int32_t> out; + p_bundle->getIntVector(*key, &out); + }, + [](FuzzedDataProvider*, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16* key) -> void { + std::vector<bool> out; + p_bundle->getBooleanVector(*key, &out); + }, + [](FuzzedDataProvider*, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16* key) -> void { + String16 out; + p_bundle->getString(*key, &out); + }, + [](FuzzedDataProvider*, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16* key) -> void { + double out; + p_bundle->getDouble(*key, &out); + }, + [](FuzzedDataProvider*, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16* key) -> void { + int64_t out; + p_bundle->getLong(*key, &out); + }, + [](FuzzedDataProvider*, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16* key) -> void { + int32_t out; + p_bundle->getInt(*key, &out); + }, + [](FuzzedDataProvider*, std::shared_ptr<os::PersistableBundle> const& p_bundle, + String16*) -> void { + p_bundle->getBooleanKeys(); + p_bundle->getIntKeys(); + p_bundle->getLongKeys(); + p_bundle->getDoubleKeys(); + p_bundle->getStringKeys(); + p_bundle->getBooleanVectorKeys(); + p_bundle->getIntVectorKeys(); + p_bundle->getLongVectorKeys(); + p_bundle->getDoubleVectorKeys(); + p_bundle->getStringVectorKeys(); + p_bundle->getPersistableBundleKeys(); + }}; + +} // namespace android diff --git a/libs/binder/tests/fuzzers/StabilityFuzz.cpp b/libs/binder/tests/fuzzers/StabilityFuzz.cpp new file mode 100644 index 0000000000..8ad9b44f65 --- /dev/null +++ b/libs/binder/tests/fuzzers/StabilityFuzz.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 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 <StabilityFuzzFunctions.h> +#include <commonFuzzHelpers.h> +#include <fuzzer/FuzzedDataProvider.h> + +// Fuzzer entry point. +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + // Init our wrapper + FuzzedDataProvider dataProvider(data, size); + android::sp<android::IBinder> bbinder = new android::BBinder(); + + // Call some functions + while (dataProvider.remaining_bytes() > 0) { + callArbitraryFunction(&dataProvider, gStabilityOperations, bbinder); + } + + return 0; +} diff --git a/libs/binder/tests/fuzzers/StabilityFuzzFunctions.h b/libs/binder/tests/fuzzers/StabilityFuzzFunctions.h new file mode 100644 index 0000000000..8b4ed702af --- /dev/null +++ b/libs/binder/tests/fuzzers/StabilityFuzzFunctions.h @@ -0,0 +1,67 @@ +/* + * 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 <binder/Binder.h> +#include <binder/Stability.h> +#include <fuzzer/FuzzedDataProvider.h> + +#define STABILITY_MAX_TAG_LENGTH 2048 +static bool marked = false; + +/* This is a vector of lambda functions the fuzzer will pull from. + * This is done so new functions can be added to the fuzzer easily + * without requiring modifications to the main fuzzer file. This also + * allows multiple fuzzers to include this file, if functionality is needed. + */ +static const std::vector< + std::function<void(FuzzedDataProvider*, android::sp<android::IBinder> const&)>> + gStabilityOperations = { + // markCompilationUnit(IBinder* binder) + [](FuzzedDataProvider*, android::sp<android::IBinder> const& bbinder) -> void { + if (!marked) { + android::internal::Stability::markCompilationUnit(bbinder.get()); + marked = true; + } + }, + + // markVintf(IBinder* binder) + [](FuzzedDataProvider*, android::sp<android::IBinder> const& bbinder) -> void { + if (!marked) { + android::internal::Stability::markVintf(bbinder.get()); + marked = true; + } + }, + + // debugLogStability(const std::string& tag, const sp<IBinder>& binder) + [](FuzzedDataProvider* fdp, android::sp<android::IBinder> const& bbinder) -> void { + std::string tag = fdp->ConsumeRandomLengthString(STABILITY_MAX_TAG_LENGTH); + android::internal::Stability::debugLogStability(tag, bbinder); + }, + + // markVndk(IBinder* binder) + [](FuzzedDataProvider*, android::sp<android::IBinder> const& bbinder) -> void { + if (!marked) { + android::internal::Stability::markVndk(bbinder.get()); + marked = true; + } + }, + + // requiresVintfDeclaration(const sp<IBinder>& binder) + [](FuzzedDataProvider*, android::sp<android::IBinder> const& bbinder) -> void { + android::internal::Stability::requiresVintfDeclaration(bbinder); + }}; diff --git a/libs/binder/tests/fuzzers/StatusFuzz.cpp b/libs/binder/tests/fuzzers/StatusFuzz.cpp new file mode 100644 index 0000000000..4f6ad6f707 --- /dev/null +++ b/libs/binder/tests/fuzzers/StatusFuzz.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 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 <StatusFuzzFunctions.h> +#include <binder/Parcel.h> +#include <binder/Status.h> +#include <commonFuzzHelpers.h> +#include <fuzzer/FuzzedDataProvider.h> +#include <utils/String8.h> +#include <cstdint> +#include <sstream> +#include <string> + +namespace android { +// Fuzzer entry point. +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + FuzzedDataProvider fdp(data, size); + + int32_t exceptionCode = fdp.ConsumeIntegral<int32_t>(); + std::string message_str = fdp.ConsumeRandomLengthString(fdp.remaining_bytes()); + String8 message(message_str.c_str()); + + Parcel parcel; + std::vector<uint8_t> buf = fdp.ConsumeBytes<uint8_t>( + fdp.ConsumeIntegralInRange<size_t>(0, fdp.remaining_bytes() - 1)); + parcel.write(buf.data(), buf.size()); + binder::Status status = binder::Status::fromExceptionCode(exceptionCode, message); + + while (fdp.remaining_bytes() > 0) { + callArbitraryFunction(&fdp, gStatusOperations, &status, &parcel); + } + return 0; +} +} // namespace android diff --git a/libs/binder/tests/fuzzers/StatusFuzzFunctions.h b/libs/binder/tests/fuzzers/StatusFuzzFunctions.h new file mode 100644 index 0000000000..bc8d17a34f --- /dev/null +++ b/libs/binder/tests/fuzzers/StatusFuzzFunctions.h @@ -0,0 +1,91 @@ +/* + * 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 <fuzzer/FuzzedDataProvider.h> + +#include <binder/Parcel.h> +#include <binder/Status.h> +#include <stdio.h> +#include <utils/String8.h> +#include <cstdint> +#include <sstream> +#include <string> + +namespace android { +/* This is a vector of lambda functions the fuzzer will pull from. + * This is done so new functions can be added to the fuzzer easily + * without requiring modifications to the main fuzzer file. This also + * allows multiple fuzzers to include this file, if functionality is needed. + */ +static const std::vector<std::function<void(FuzzedDataProvider*, binder::Status*, Parcel*)>> + gStatusOperations = { + [](FuzzedDataProvider*, binder::Status* status, Parcel* parcel) -> void { + parcel->setDataPosition(0); + status->readFromParcel(*parcel); + }, + [](FuzzedDataProvider*, binder::Status* status, Parcel* parcel) -> void { + status->writeToParcel(parcel); + }, + [](FuzzedDataProvider* fdp, binder::Status* status, Parcel*) -> void { + std::string message_str = + fdp->ConsumeRandomLengthString(fdp->remaining_bytes()); + String8 message(message_str.c_str()); + status->setServiceSpecificError(fdp->ConsumeIntegral<int32_t>(), message); + }, + [](FuzzedDataProvider* fdp, binder::Status* status, Parcel*) -> void { + std::string message_str = + fdp->ConsumeRandomLengthString(fdp->remaining_bytes()); + String8 message(message_str.c_str()); + status->setException(fdp->ConsumeIntegral<int32_t>(), message); + }, + [](FuzzedDataProvider*, binder::Status* status, Parcel*) -> void { status->ok(); }, + [](FuzzedDataProvider* fdp, binder::Status* status, Parcel*) -> void { + std::string message_str = + fdp->ConsumeRandomLengthString(fdp->remaining_bytes()); + String8 message(message_str.c_str()); + *status = binder::Status::fromExceptionCode(fdp->ConsumeIntegral<int32_t>(), + message); + }, + [](FuzzedDataProvider* fdp, binder::Status* status, Parcel*) -> void { + *status = binder::Status::fromServiceSpecificError( + fdp->ConsumeIntegral<int32_t>()); + }, + [](FuzzedDataProvider* fdp, binder::Status*, Parcel*) -> void { + binder::Status::exceptionToString(fdp->ConsumeIntegral<int32_t>()); + }, + [](FuzzedDataProvider* fdp, binder::Status* status, Parcel*) -> void { + std::string message_str = + fdp->ConsumeRandomLengthString(fdp->remaining_bytes()); + String8 message(message_str.c_str()); + *status = binder::Status::fromServiceSpecificError(fdp->ConsumeIntegral< + int32_t>(), + message); + }, + [](FuzzedDataProvider* fdp, binder::Status* status, Parcel*) -> void { + *status = binder::Status::fromStatusT(fdp->ConsumeIntegral<status_t>()); + }, + [](FuzzedDataProvider* fdp, binder::Status* status, Parcel*) -> void { + status->setFromStatusT(fdp->ConsumeIntegral<status_t>()); + }, + [](FuzzedDataProvider*, binder::Status* status, Parcel*) -> void { + std::stringstream ss; + ss << *status; + }, +}; + +} // namespace android diff --git a/libs/binder/tests/fuzzers/TextOutputFuzz.cpp b/libs/binder/tests/fuzzers/TextOutputFuzz.cpp new file mode 100644 index 0000000000..c9500205df --- /dev/null +++ b/libs/binder/tests/fuzzers/TextOutputFuzz.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (C) 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 <binder/Debug.h> +#include <binder/Parcel.h> +#include <binder/TextOutput.h> +#include "android-base/file.h" +#include "android-base/test_utils.h" + +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <cstddef> +#include <limits> + +// Fuzzer for the TextOutput class. These were lifted from the existing +// test suite. +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + FuzzedDataProvider fdp(data, size); + CapturedStderr cap; + + while (fdp.remaining_bytes() > 1) { + switch (fdp.ConsumeIntegral<uint8_t>() % 3) { + case 0: { + std::string input = fdp.ConsumeBytesAsString( + fdp.ConsumeIntegralInRange<size_t>(0, fdp.remaining_bytes())); + android::aerr << input << android::endl; + break; + } + case 1: { + std::string str = fdp.ConsumeRandomLengthString(fdp.remaining_bytes()); + android::HexDump input(str.c_str(), sizeof(str.c_str())); + android::aerr << input << android::endl; + break; + } + case 2: { + android::TypeCode input(fdp.ConsumeIntegral<uint32_t>()); + android::aerr << input << android::endl; + } + } + } + cap.Stop(); + + return 0; +} diff --git a/libs/binder/tests/fuzzers/commonFuzzHelpers.h b/libs/binder/tests/fuzzers/commonFuzzHelpers.h new file mode 100644 index 0000000000..d58d9b6d84 --- /dev/null +++ b/libs/binder/tests/fuzzers/commonFuzzHelpers.h @@ -0,0 +1,41 @@ +/* + * 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 <fuzzer/FuzzedDataProvider.h> +#include <vector> + +// Calls a function from the ops_vector +template <class F, class T, class... Types> +void callArbitraryFunction(F* fdp, T const& ops_vector, Types... args) { + // Choose which function we'll be calling + uint8_t function_id = fdp->template ConsumeIntegralInRange<uint8_t>(0, ops_vector.size() - 1); + + // Call the function we've chosen + ops_vector[function_id](fdp, args...); +} + +template <class T> +T getArbitraryVectorElement(FuzzedDataProvider* fdp, std::vector<T> const& vect, bool allow_null) { + // If we're allowing null, give it a 50:50 shot at returning a nullptr + if (vect.empty() || (allow_null && fdp->ConsumeBool())) { + return nullptr; + } + + // Otherwise, return an element from our vector + return vect.at(fdp->ConsumeIntegralInRange<size_t>(0, vect.size() - 1)); +} |