Adds fuzzers for libmediautils
This change adds fuzzers for a few classes in libmediautils.
Test: Ran on Pixel 3a device for a short period. Estimated coverage is 2.94%.
Signed-off-by: Dylan Katz <dylan.katz@leviathansecurity.com>
Change-Id: I147122092659206800d92c4ebd373f692ea1bdb3
diff --git a/media/utils/fuzzers/Android.bp b/media/utils/fuzzers/Android.bp
new file mode 100644
index 0000000..ca1123c
--- /dev/null
+++ b/media/utils/fuzzers/Android.bp
@@ -0,0 +1,51 @@
+cc_defaults {
+ name: "libmediautils_fuzzer_defaults",
+ shared_libs: [
+ "libbinder",
+ "libcutils",
+ "liblog",
+ "libmediautils",
+ "libutils",
+ ],
+
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ "-Wno-c++2a-extensions",
+ ],
+
+ header_libs: [
+ "bionic_libc_platform_headers",
+ "libmedia_headers",
+ ],
+
+ include_dirs: [
+ // For DEBUGGER_SIGNAL
+ "system/core/debuggerd/include",
+ ],
+}
+
+cc_fuzz {
+ name: "libmediautils_fuzzer_battery_notifier",
+ defaults: ["libmediautils_fuzzer_defaults"],
+ srcs: ["BatteryNotifierFuzz.cpp"],
+}
+
+cc_fuzz {
+ name: "libmediautils_fuzzer_scheduling_policy_service",
+ defaults: ["libmediautils_fuzzer_defaults"],
+ srcs: ["SchedulingPolicyServiceFuzz.cpp"],
+}
+
+cc_fuzz {
+ name: "libmediautils_fuzzer_service_utilities",
+ defaults: ["libmediautils_fuzzer_defaults"],
+ srcs: ["ServiceUtilitiesFuzz.cpp"],
+}
+
+cc_fuzz {
+ name: "libmediautils_fuzzer_time_check",
+ defaults: ["libmediautils_fuzzer_defaults"],
+ srcs: ["TimeCheckFuzz.cpp"],
+}
diff --git a/media/utils/fuzzers/BatteryNotifierFuzz.cpp b/media/utils/fuzzers/BatteryNotifierFuzz.cpp
new file mode 100644
index 0000000..00b3cce
--- /dev/null
+++ b/media/utils/fuzzers/BatteryNotifierFuzz.cpp
@@ -0,0 +1,90 @@
+/*
+ * 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 <string>
+#include <vector>
+
+#include <utils/String8.h>
+
+#include "fuzzer/FuzzedDataProvider.h"
+#include "mediautils/BatteryNotifier.h"
+
+static constexpr int kMaxOperations = 30;
+static constexpr int kMaxStringLength = 500;
+using android::BatteryNotifier;
+
+std::vector<std::function<void(std::string /*flashlight_name*/, std::string /*camera_name*/,
+ uid_t /*video_id*/, uid_t /*audio_id*/, uid_t /*light_id*/,
+ uid_t /*camera_id*/)>>
+ operations = {
+ [](std::string, std::string, uid_t, uid_t, uid_t, uid_t) -> void {
+ BatteryNotifier::getInstance().noteResetVideo();
+ },
+ [](std::string, std::string, uid_t, uid_t, uid_t, uid_t) -> void {
+ BatteryNotifier::getInstance().noteResetAudio();
+ },
+ [](std::string, std::string, uid_t, uid_t, uid_t, uid_t) -> void {
+ BatteryNotifier::getInstance().noteResetFlashlight();
+ },
+ [](std::string, std::string, uid_t, uid_t, uid_t, uid_t) -> void {
+ BatteryNotifier::getInstance().noteResetCamera();
+ },
+ [](std::string, std::string, uid_t video_id, uid_t, uid_t, uid_t) -> void {
+ BatteryNotifier::getInstance().noteStartVideo(video_id);
+ },
+ [](std::string, std::string, uid_t video_id, uid_t, uid_t, uid_t) -> void {
+ BatteryNotifier::getInstance().noteStopVideo(video_id);
+ },
+ [](std::string, std::string, uid_t, uid_t audio_id, uid_t, uid_t) -> void {
+ BatteryNotifier::getInstance().noteStartAudio(audio_id);
+ },
+ [](std::string, std::string, uid_t, uid_t audio_id, uid_t, uid_t) -> void {
+ BatteryNotifier::getInstance().noteStopAudio(audio_id);
+ },
+ [](std::string flashlight_name, std::string, uid_t, uid_t, uid_t light_id, uid_t) -> void {
+ android::String8 name(flashlight_name.c_str());
+ BatteryNotifier::getInstance().noteFlashlightOn(name, light_id);
+ },
+ [](std::string flashlight_name, std::string, uid_t, uid_t, uid_t light_id, uid_t) -> void {
+ android::String8 name(flashlight_name.c_str());
+ BatteryNotifier::getInstance().noteFlashlightOff(name, light_id);
+ },
+ [](std::string, std::string camera_name, uid_t, uid_t, uid_t, uid_t camera_id) -> void {
+ android::String8 name(camera_name.c_str());
+ BatteryNotifier::getInstance().noteStartCamera(name, camera_id);
+ },
+ [](std::string, std::string camera_name, uid_t, uid_t, uid_t, uid_t camera_id) -> void {
+ android::String8 name(camera_name.c_str());
+ BatteryNotifier::getInstance().noteStopCamera(name, camera_id);
+ },
+};
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ FuzzedDataProvider data_provider(data, size);
+ std::string camera_name = data_provider.ConsumeRandomLengthString(kMaxStringLength);
+ std::string flashlight_name = data_provider.ConsumeRandomLengthString(kMaxStringLength);
+ uid_t video_id = data_provider.ConsumeIntegral<uid_t>();
+ uid_t audio_id = data_provider.ConsumeIntegral<uid_t>();
+ uid_t light_id = data_provider.ConsumeIntegral<uid_t>();
+ uid_t camera_id = data_provider.ConsumeIntegral<uid_t>();
+ size_t ops_run = 0;
+ while (data_provider.remaining_bytes() > 0 && ops_run++ < kMaxOperations) {
+ uint8_t op = data_provider.ConsumeIntegralInRange<uint8_t>(0, operations.size() - 1);
+ operations[op](flashlight_name, camera_name, video_id, audio_id, light_id, camera_id);
+ }
+ return 0;
+}
diff --git a/media/utils/fuzzers/SchedulingPolicyServiceFuzz.cpp b/media/utils/fuzzers/SchedulingPolicyServiceFuzz.cpp
new file mode 100644
index 0000000..4521853
--- /dev/null
+++ b/media/utils/fuzzers/SchedulingPolicyServiceFuzz.cpp
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+#define LOG_TAG "BatteryNotifierFuzzer"
+#include <binder/IBatteryStats.h>
+#include <binder/IServiceManager.h>
+#include <utils/String16.h>
+#include <android/log.h>
+#include <mediautils/SchedulingPolicyService.h>
+#include "fuzzer/FuzzedDataProvider.h"
+using android::IBatteryStats;
+using android::IBinder;
+using android::IInterface;
+using android::IServiceManager;
+using android::sp;
+using android::String16;
+using android::defaultServiceManager;
+using android::requestCpusetBoost;
+using android::requestPriority;
+sp<IBatteryStats> getBatteryService() {
+ sp<IBatteryStats> batteryStatService;
+ const sp<IServiceManager> sm(defaultServiceManager());
+ if (sm != nullptr) {
+ const String16 name("batterystats");
+ batteryStatService = checked_interface_cast<IBatteryStats>(sm->checkService(name));
+ if (batteryStatService == nullptr) {
+ ALOGW("batterystats service unavailable!");
+ return nullptr;
+ }
+ }
+ return batteryStatService;
+}
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ FuzzedDataProvider data_provider(data, size);
+ sp<IBatteryStats> batteryStatService = getBatteryService();
+ // There is some state here, but it's mostly focused around thread-safety, so
+ // we won't worry about order.
+ int32_t priority = data_provider.ConsumeIntegral<int32_t>();
+ bool is_for_app = data_provider.ConsumeBool();
+ bool async = data_provider.ConsumeBool();
+ requestPriority(getpid(), gettid(), priority, is_for_app, async);
+ // TODO: Verify and re-enable in AOSP (R).
+ // bool enable = data_provider.ConsumeBool();
+ // We are just using batterystats to avoid the need
+ // to register a new service.
+ // requestCpusetBoost(enable, IInterface::asBinder(batteryStatService));
+ return 0;
+}
+
diff --git a/media/utils/fuzzers/ServiceUtilitiesFuzz.cpp b/media/utils/fuzzers/ServiceUtilitiesFuzz.cpp
new file mode 100644
index 0000000..3d141b5
--- /dev/null
+++ b/media/utils/fuzzers/ServiceUtilitiesFuzz.cpp
@@ -0,0 +1,78 @@
+/*
+ * 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 <fcntl.h>
+
+#include <functional>
+
+#include "fuzzer/FuzzedDataProvider.h"
+#include "mediautils/ServiceUtilities.h"
+
+static constexpr int kMaxOperations = 50;
+static constexpr int kMaxStringLen = 256;
+
+const std::vector<std::function<void(FuzzedDataProvider*, android::MediaPackageManager)>>
+ operations = {
+ [](FuzzedDataProvider* data_provider, android::MediaPackageManager pm) -> void {
+ uid_t uid = data_provider->ConsumeIntegral<uid_t>();
+ pm.allowPlaybackCapture(uid);
+ },
+ [](FuzzedDataProvider* data_provider, android::MediaPackageManager pm) -> void {
+ int spaces = data_provider->ConsumeIntegral<int>();
+
+ // Dump everything into /dev/null
+ int fd = open("/dev/null", O_WRONLY);
+ pm.dump(fd, spaces);
+ close(fd);
+ },
+};
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ FuzzedDataProvider data_provider(data, size);
+ uid_t uid = data_provider.ConsumeIntegral<uid_t>();
+ pid_t pid = data_provider.ConsumeIntegral<pid_t>();
+
+ // There is not state here, and order is not significant,
+ // so we can simply call all of the target functions
+ android::isServiceUid(uid);
+ android::isAudioServerUid(uid);
+ android::isAudioServerOrSystemServerUid(uid);
+ android::isAudioServerOrMediaServerUid(uid);
+ std::string packageNameStr = data_provider.ConsumeRandomLengthString(kMaxStringLen);
+ android::String16 opPackageName(packageNameStr.c_str());
+ android::recordingAllowed(opPackageName, pid, uid);
+ android::startRecording(opPackageName, pid, uid);
+ android::finishRecording(opPackageName, uid);
+ android::captureAudioOutputAllowed(pid, uid);
+ android::captureMediaOutputAllowed(pid, uid);
+ android::captureHotwordAllowed(opPackageName, pid, uid);
+ android::modifyPhoneStateAllowed(uid, pid);
+ android::bypassInterruptionPolicyAllowed(uid, pid);
+ android::settingsAllowed();
+ android::modifyAudioRoutingAllowed();
+ android::modifyDefaultAudioEffectsAllowed();
+ android::dumpAllowed();
+
+ // MediaPackageManager does have state, so we need the fuzzer to decide order
+ android::MediaPackageManager packageManager;
+ size_t ops_run = 0;
+ while (data_provider.remaining_bytes() > 0 && ops_run++ < kMaxOperations) {
+ uint8_t op = data_provider.ConsumeIntegralInRange<uint8_t>(0, operations.size() - 1);
+ operations[op](&data_provider, packageManager);
+ }
+
+ return 0;
+}
diff --git a/media/utils/fuzzers/TimeCheckFuzz.cpp b/media/utils/fuzzers/TimeCheckFuzz.cpp
new file mode 100644
index 0000000..eeb6ba6
--- /dev/null
+++ b/media/utils/fuzzers/TimeCheckFuzz.cpp
@@ -0,0 +1,64 @@
+/*
+ * 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 <chrono>
+#include <thread>
+
+#include "fuzzer/FuzzedDataProvider.h"
+#include "mediautils/TimeCheck.h"
+
+static constexpr int kMaxStringLen = 256;
+
+// While it might be interesting to test long-running
+// jobs, it seems unlikely it'd lead to the types of crashes
+// we're looking for, and would mean a significant increase in fuzzer time.
+// Therefore, we are setting a low cap.
+static constexpr uint32_t kMaxTimeoutMs = 1000;
+static constexpr uint32_t kMinTimeoutMs = 200;
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ FuzzedDataProvider data_provider(data, size);
+
+ // There's essentially 5 operations that we can access in this class
+ // 1. The time it takes to run this operation. As mentioned above,
+ // long-running tasks are not good for fuzzing, but there will be
+ // some change in the run time.
+ uint32_t timeoutMs =
+ data_provider.ConsumeIntegralInRange<uint32_t>(kMinTimeoutMs, kMaxTimeoutMs);
+ uint8_t pid_size = data_provider.ConsumeIntegral<uint8_t>();
+ std::vector<pid_t> pids(pid_size);
+ for (auto& pid : pids) {
+ pid = data_provider.ConsumeIntegral<pid_t>();
+ }
+
+ // 2. We also have setAudioHalPids, which is populated with the pids set
+ // above.
+ android::TimeCheck::setAudioHalPids(pids);
+ std::string name = data_provider.ConsumeRandomLengthString(kMaxStringLen);
+
+ // 3. The constructor, which is fuzzed here:
+ android::TimeCheck timeCheck(name.c_str(), timeoutMs);
+ // We will leave some buffer to avoid sleeping too long
+ uint8_t sleep_amount_ms = data_provider.ConsumeIntegralInRange<uint8_t>(0, timeoutMs / 2);
+
+ // We want to make sure we can cover the time out functionality.
+ if (sleep_amount_ms) {
+ auto ms = std::chrono::milliseconds(sleep_amount_ms);
+ std::this_thread::sleep_for(ms);
+ }
+
+ // 4. Finally, the destructor on timecheck. These seem to be the only factors
+ // in play.
+ return 0;
+}