Adding multiple fuzzers for libbinder.
Adding fuzzers in libbinder for Binder, BpBinder, MemoryHeapBase, ParcelBlob, PersistableBundle, Stability, Status, and TextOutput. These follow the same framework style.
Test: Tested on a Pixel3a device for 500k iterations each.
Signed-off-by: Corbin Souffrant <corbin.souffrant@leviathansecurity.com>
Change-Id: I53b85570a3abde854b01ffefc2739b79b39af7e2
diff --git a/libs/binder/tests/fuzzers/Android.bp b/libs/binder/tests/fuzzers/Android.bp
new file mode 100644
index 0000000..46379fc
--- /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 0000000..1e5d80a
--- /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 0000000..9ac65bb
--- /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 0000000..c50279b
--- /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 0000000..c685b41
--- /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 0000000..626b758
--- /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 0000000..4843c46
--- /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 0000000..820e9e8
--- /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 0000000..8ad9b44
--- /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 0000000..8b4ed70
--- /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 0000000..4f6ad6f
--- /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 0000000..bc8d17a
--- /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 0000000..c950020
--- /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 0000000..d58d9b6
--- /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));
+}